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 2018/10/02 12:32:17 UTC
[1/6] syncope git commit: [SYNCOPE-1369] User requests forms now
support dropdowns - via Flowable customization
Repository: syncope
Updated Branches:
refs/heads/2_1_X 35d46cfe3 -> 6f6d91569
refs/heads/master fba9bce62 -> fee1317dc
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserRequestLogic.java
----------------------------------------------------------------------
diff --git a/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserRequestLogic.java b/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserRequestLogic.java
index 1acc1da..686677e 100644
--- a/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserRequestLogic.java
+++ b/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserRequestLogic.java
@@ -25,13 +25,12 @@ import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.patch.UserPatch;
import org.apache.syncope.common.lib.to.PropagationTaskTO;
-import org.apache.syncope.common.lib.to.UserRequestTO;
+import org.apache.syncope.common.lib.to.UserRequest;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.to.UserRequestForm;
import org.apache.syncope.common.lib.types.BpmnProcessFormat;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.FlowableEntitlement;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.syncope.core.flowable.api.BpmnProcessManager;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
@@ -41,6 +40,7 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecu
import org.apache.syncope.core.provisioning.api.WorkflowResult;
import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
import org.apache.syncope.core.flowable.api.UserRequestHandler;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
@@ -52,24 +52,49 @@ import org.springframework.transaction.annotation.Transactional;
public class UserRequestLogic extends AbstractTransactionalLogic<UserRequestForm> {
@Autowired
- private BpmnProcessManager bpmnProcessManager;
+ protected BpmnProcessManager bpmnProcessManager;
@Autowired
- private UserRequestHandler userRequestHandler;
+ protected UserRequestHandler userRequestHandler;
@Autowired
- private PropagationManager propagationManager;
+ protected PropagationManager propagationManager;
@Autowired
- private PropagationTaskExecutor taskExecutor;
+ protected PropagationTaskExecutor taskExecutor;
@Autowired
- private UserDataBinder binder;
+ protected UserDataBinder binder;
@Autowired
- private UserDAO userDAO;
+ protected UserDAO userDAO;
- protected UserRequestTO doStart(final String bpmnProcess, final User user) {
+ @PreAuthorize("isAuthenticated()")
+ @Transactional(readOnly = true)
+ public Pair<Integer, List<UserRequest>> list(final String userKey,
+ final int page,
+ final int size,
+ final List<OrderByClause> orderByClauses) {
+
+ if (userKey == null) {
+ securityChecks(null,
+ FlowableEntitlement.USER_REQUEST_LIST,
+ "Listing user requests not allowed");
+ } else {
+ User user = userDAO.find(userKey);
+ if (user == null) {
+ throw new NotFoundException("User " + userKey);
+ }
+
+ securityChecks(user.getUsername(),
+ FlowableEntitlement.USER_REQUEST_LIST,
+ "Listing requests for user" + user.getUsername() + " not allowed");
+ }
+
+ return userRequestHandler.getUserRequests(userKey, page, size, orderByClauses);
+ }
+
+ protected UserRequest doStart(final String bpmnProcess, final User user) {
// check if BPMN process exists
bpmnProcessManager.exportProcess(bpmnProcess, BpmnProcessFormat.XML, new NullOutputStream());
@@ -77,56 +102,84 @@ public class UserRequestLogic extends AbstractTransactionalLogic<UserRequestForm
}
@PreAuthorize("isAuthenticated()")
- public UserRequestTO start(final String bpmnProcess) {
+ public UserRequest start(final String bpmnProcess) {
return doStart(bpmnProcess, userDAO.findByUsername(AuthContextUtils.getUsername()));
}
@PreAuthorize("hasRole('" + FlowableEntitlement.USER_REQUEST_START + "')")
- public UserRequestTO start(final String bpmnProcess, final String userKey) {
+ public UserRequest start(final String bpmnProcess, final String userKey) {
return doStart(bpmnProcess, userDAO.authFind(userKey));
}
- @PreAuthorize("isAuthenticated()")
- public void cancel(final String executionId, final String reason) {
- Pair<ProcessInstance, String> parsed = userRequestHandler.parse(executionId);
-
- if (!AuthContextUtils.getUsername().equals(userDAO.find(parsed.getRight()).getUsername())
+ protected void securityChecks(final String username, final String entitlement, final String errorMessage) {
+ if (!AuthContextUtils.getUsername().equals(username)
&& !AuthContextUtils.getAuthorities().stream().
- anyMatch(auth -> FlowableEntitlement.USER_REQUEST_CANCEL.equals(auth.getAuthority()))) {
+ anyMatch(auth -> entitlement.equals(auth.getAuthority()))) {
SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.DelegatedAdministration);
- sce.getElements().add("Canceling " + executionId + " not allowed");
+ sce.getElements().add(errorMessage);
throw sce;
}
+ }
+
+ @PreAuthorize("isAuthenticated()")
+ public void cancel(final String executionId, final String reason) {
+ Pair<ProcessInstance, String> parsed = userRequestHandler.parse(executionId);
+
+ securityChecks(userDAO.find(parsed.getRight()).getUsername(),
+ FlowableEntitlement.USER_REQUEST_CANCEL,
+ "Canceling " + executionId + " not allowed");
userRequestHandler.cancel(parsed.getLeft(), reason);
}
- @PreAuthorize("hasRole('" + FlowableEntitlement.WORKFLOW_FORM_CLAIM + "')")
+ @PreAuthorize("isAuthenticated()")
public UserRequestForm claimForm(final String taskId) {
- return userRequestHandler.claimForm(taskId);
- }
-
- @PreAuthorize("hasRole('" + FlowableEntitlement.WORKFLOW_FORM_READ + "') "
- + "and hasRole('" + StandardEntitlement.USER_READ + "')")
- @Transactional(readOnly = true)
- public List<UserRequestForm> getForms(final String key) {
- User user = userDAO.authFind(key);
- return userRequestHandler.getForms(user.getKey());
+ UserRequestForm form = userRequestHandler.claimForm(taskId);
+ securityChecks(form.getUsername(),
+ FlowableEntitlement.USER_REQUEST_FORM_CLAIM,
+ "Claiming form " + taskId + " not allowed");
+ return form;
}
- @PreAuthorize("hasRole('" + FlowableEntitlement.WORKFLOW_FORM_LIST + "')")
+ @PreAuthorize("isAuthenticated()")
@Transactional(readOnly = true)
public Pair<Integer, List<UserRequestForm>> getForms(
+ final String userKey,
final int page,
final int size,
final List<OrderByClause> orderByClauses) {
- return userRequestHandler.getForms(page, size, orderByClauses);
+ if (userKey == null) {
+ securityChecks(null,
+ FlowableEntitlement.USER_REQUEST_FORM_LIST,
+ "Listing forms not allowed");
+ } else {
+ User user = userDAO.find(userKey);
+ if (user == null) {
+ throw new NotFoundException("User " + userKey);
+ }
+
+ securityChecks(user.getUsername(),
+ FlowableEntitlement.USER_REQUEST_FORM_LIST,
+ "Listing forms for user" + user.getUsername() + " not allowed");
+ }
+
+ return userRequestHandler.getForms(userKey, page, size, orderByClauses);
}
- @PreAuthorize("hasRole('" + FlowableEntitlement.WORKFLOW_FORM_SUBMIT + "')")
+ @PreAuthorize("isAuthenticated()")
public UserTO submitForm(final UserRequestForm form) {
+ if (form.getUsername() == null) {
+ securityChecks(null,
+ FlowableEntitlement.USER_REQUEST_FORM_SUBMIT,
+ "Submitting forms not allowed");
+ } else {
+ securityChecks(form.getUsername(),
+ FlowableEntitlement.USER_REQUEST_FORM_SUBMIT,
+ "Submitting forms for user" + form.getUsername() + " not allowed");
+ }
+
WorkflowResult<UserPatch> wfResult = userRequestHandler.submitForm(form);
// propByRes can be made empty by the workflow definition if no propagation should occur
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestFormQuery.java
----------------------------------------------------------------------
diff --git a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestFormQuery.java b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestFormQuery.java
index 4097afd..c4ac3a0 100644
--- a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestFormQuery.java
+++ b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestFormQuery.java
@@ -18,6 +18,8 @@
*/
package org.apache.syncope.common.rest.api.beans;
+import javax.ws.rs.QueryParam;
+
public class UserRequestFormQuery extends AbstractQuery {
private static final long serialVersionUID = -4762457303770028554L;
@@ -28,5 +30,21 @@ public class UserRequestFormQuery extends AbstractQuery {
protected UserRequestFormQuery newInstance() {
return new UserRequestFormQuery();
}
+
+ public Builder user(final String user) {
+ getInstance().setUser(user);
+ return this;
+ }
+ }
+
+ private String user;
+
+ public String getUser() {
+ return user;
+ }
+
+ @QueryParam("user")
+ public void setUser(final String user) {
+ this.user = user;
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestQuery.java
----------------------------------------------------------------------
diff --git a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestQuery.java b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestQuery.java
new file mode 100644
index 0000000..3f53629
--- /dev/null
+++ b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestQuery.java
@@ -0,0 +1,50 @@
+/*
+ * 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.beans;
+
+import javax.ws.rs.QueryParam;
+
+public class UserRequestQuery extends AbstractQuery {
+
+ private static final long serialVersionUID = 427312034580076640L;
+
+ public static class Builder extends AbstractQuery.Builder<UserRequestQuery, Builder> {
+
+ @Override
+ protected UserRequestQuery newInstance() {
+ return new UserRequestQuery();
+ }
+
+ public Builder user(final String user) {
+ getInstance().setUser(user);
+ return this;
+ }
+ }
+
+ private String user;
+
+ public String getUser() {
+ return user;
+ }
+
+ @QueryParam("user")
+ public void setUser(final String user) {
+ this.user = user;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/BpmnProcessService.java
----------------------------------------------------------------------
diff --git a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/BpmnProcessService.java b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/BpmnProcessService.java
index 06cb056..bb34fdd 100644
--- a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/BpmnProcessService.java
+++ b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/BpmnProcessService.java
@@ -19,6 +19,9 @@
package org.apache.syncope.common.rest.api.service;
import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.ArraySchema;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
@@ -35,7 +38,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.common.rest.api.RESTHeaders;
/**
@@ -51,11 +54,16 @@ public interface BpmnProcessService extends JAXRSService {
/**
* Lists the available BPMN processes.
*
- * @return available BPMN processs, for the given any object type
+ * @return available BPMN processs
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "available BPMN processes", content =
+ @Content(array =
+ @ArraySchema(schema =
+ @Schema(implementation = BpmnProcess.class)))))
@GET
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
- List<BpmnProcessTO> list();
+ List<BpmnProcess> list();
/**
* Exports the BPMN process for matching key.
@@ -63,6 +71,8 @@ public interface BpmnProcessService extends JAXRSService {
* @param key BPMN process key
* @return BPMN process for matching key
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "BPMN process for matching key"))
@GET
@Path("{key}")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@@ -72,8 +82,10 @@ public interface BpmnProcessService extends JAXRSService {
* Exports the BPMN diagram representation (if available), for matching key.
*
* @param key BPMN process key
- * @return workflow diagram representation
+ * @return BPMN diagram representation
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "BPMN diagram representation"))
@GET
@Path("{key}/diagram.png")
@Produces({ RESTHeaders.MEDIATYPE_IMAGE_PNG })
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserRequestService.java
----------------------------------------------------------------------
diff --git a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserRequestService.java b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserRequestService.java
index 701772d..5ad7b12 100644
--- a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserRequestService.java
+++ b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserRequestService.java
@@ -18,10 +18,13 @@
*/
package org.apache.syncope.common.rest.api.service;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.security.SecurityRequirements;
import io.swagger.v3.oas.annotations.tags.Tag;
-import java.util.List;
import javax.validation.constraints.NotNull;
import javax.ws.rs.BeanParam;
import javax.ws.rs.Consumes;
@@ -34,11 +37,12 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.UserRequestTO;
+import org.apache.syncope.common.lib.to.UserRequest;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.to.UserRequestForm;
import org.apache.syncope.common.rest.api.RESTHeaders;
import org.apache.syncope.common.rest.api.beans.UserRequestFormQuery;
+import org.apache.syncope.common.rest.api.beans.UserRequestQuery;
/**
* REST operations related to user workflow.
@@ -51,19 +55,37 @@ import org.apache.syncope.common.rest.api.beans.UserRequestFormQuery;
public interface UserRequestService extends JAXRSService {
/**
- * Starts a new user request, for the given BOMN Process and
- * user (if provided) or requesting user (if not provided).
+ * Returns a list of running user requests matching the given query.
+ *
+ * @param query query conditions
+ * @return list of all running user requests
+ */
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "list of all running user requests", content =
+ @Content(schema =
+ @Schema(implementation = PagedResult.class))))
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ PagedResult<UserRequest> list(@BeanParam UserRequestQuery query);
+
+ /**
+ * Starts a new request for the given BPMN Process and user (if provided) or requesting user (if not provided).
*
* @param bpmnProcess BPMN process
- * @param userKey user key
+ * @param user if value looks like a UUID then it is interpreted as key otherwise as a username
* @return data about the started request service, including execution id
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200",
+ description = "data about the started request service, including execution id", content =
+ @Content(schema =
+ @Schema(implementation = UserRequest.class))))
@POST
@Path("start/{bpmnProcess}")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
- UserRequestTO start(
+ UserRequest start(
@NotNull @PathParam("bpmnProcess") String bpmnProcess,
- @QueryParam("userKey") String userKey);
+ @QueryParam("user") String user);
/**
* Cancel a running user request.
@@ -71,6 +93,8 @@ public interface UserRequestService extends JAXRSService {
* @param executionId execution id
* @param reason reason to cancel the user request
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "204", description = "Operation was successful"))
@DELETE
@Path("{executionId}")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
@@ -79,44 +103,45 @@ public interface UserRequestService extends JAXRSService {
@QueryParam("reason") String reason);
/**
- * Returns a list of all available workflow forms.
+ * Returns a list of user request forms matching the given query.
*
* @param query query conditions
- * @return list of all available workflow forms
+ * @return list of all available user request forms
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "list of all available user request forms", content =
+ @Content(schema =
+ @Schema(implementation = PagedResult.class))))
@GET
@Path("forms")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
PagedResult<UserRequestForm> getForms(@BeanParam UserRequestFormQuery query);
/**
- * Returns a list of available forms for the given user key.
- *
- * @param userKey user key
- * @return list of available forms for the given user key
- */
- @GET
- @Path("forms/{userKey}")
- @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
- List<UserRequestForm> getForms(@NotNull @PathParam("userKey") String userKey);
-
- /**
- * Claims the form for the given task id.
+ * Requests to manage the form for the given task id.
*
* @param taskId workflow task id
- * @return the workflow form for the given task id
+ * @return the form for the given task id
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "the form for the given task id", content =
+ @Content(schema =
+ @Schema(implementation = UserRequestForm.class))))
@POST
@Path("forms/{taskId}/claim")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
UserRequestForm claimForm(@NotNull @PathParam("taskId") String taskId);
/**
- * Submits a workflow form.
+ * Submits a user request form.
*
- * @param form workflow form.
+ * @param form user request form.
* @return updated user
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "updated user", content =
+ @Content(schema =
+ @Schema(implementation = UserTO.class))))
@POST
@Path("forms")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserWorkflowTaskService.java
----------------------------------------------------------------------
diff --git a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserWorkflowTaskService.java b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserWorkflowTaskService.java
index 54f38d0..b396d6e 100644
--- a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserWorkflowTaskService.java
+++ b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserWorkflowTaskService.java
@@ -18,6 +18,11 @@
*/
package org.apache.syncope.common.rest.api.service;
+import io.swagger.v3.oas.annotations.media.ArraySchema;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.security.SecurityRequirements;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -48,6 +53,11 @@ public interface UserWorkflowTaskService extends JAXRSService {
* @param userKey user key
* @return list of available tasks for the given user key
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "list of available tasks for the given user key", content =
+ @Content(array =
+ @ArraySchema(schema =
+ @Schema(implementation = WorkflowTask.class)))))
@GET
@Path("tasks/{userKey}")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
@@ -59,6 +69,10 @@ public interface UserWorkflowTaskService extends JAXRSService {
* @param workflowTaskExecInput input for task execution
* @return updated user
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "updated user", content =
+ @Content(schema =
+ @Schema(implementation = UserTO.class))))
@POST
@Path("tasks/{userKey}")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/BpmnProcessServiceImpl.java
----------------------------------------------------------------------
diff --git a/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/BpmnProcessServiceImpl.java b/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/BpmnProcessServiceImpl.java
index dd1aea8..4f976b5 100644
--- a/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/BpmnProcessServiceImpl.java
+++ b/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/BpmnProcessServiceImpl.java
@@ -22,7 +22,7 @@ import java.util.List;
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.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.common.lib.types.BpmnProcessFormat;
import org.apache.syncope.common.rest.api.RESTHeaders;
import org.apache.syncope.core.logic.BpmnProcessLogic;
@@ -37,7 +37,7 @@ public class BpmnProcessServiceImpl extends AbstractServiceImpl implements BpmnP
private BpmnProcessLogic logic;
@Override
- public List<BpmnProcessTO> list() {
+ public List<BpmnProcess> list() {
return logic.list();
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserRequestServiceImpl.java
----------------------------------------------------------------------
diff --git a/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserRequestServiceImpl.java b/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserRequestServiceImpl.java
index 2f174a0..188d22e 100644
--- a/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserRequestServiceImpl.java
+++ b/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserRequestServiceImpl.java
@@ -21,14 +21,16 @@ package org.apache.syncope.core.rest.cxf.service;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.UserRequestTO;
+import org.apache.syncope.common.lib.to.UserRequest;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.to.UserRequestForm;
import org.apache.syncope.common.rest.api.beans.UserRequestFormQuery;
+import org.apache.syncope.common.rest.api.beans.UserRequestQuery;
import org.apache.syncope.core.logic.UserRequestLogic;
+import org.apache.syncope.common.rest.api.service.UserRequestService;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
-import org.apache.syncope.common.rest.api.service.UserRequestService;
@Service
public class UserRequestServiceImpl extends AbstractServiceImpl implements UserRequestService {
@@ -36,11 +38,25 @@ public class UserRequestServiceImpl extends AbstractServiceImpl implements UserR
@Autowired
private UserRequestLogic logic;
+ @Autowired
+ private UserDAO userDAO;
+
+ @Override
+ public PagedResult<UserRequest> list(final UserRequestQuery query) {
+ if (query.getUser() != null) {
+ query.setUser(getActualKey(userDAO, query.getUser()));
+ }
+
+ Pair<Integer, List<UserRequest>> result = logic.list(
+ query.getUser(), query.getPage(), query.getSize(), getOrderByClauses(query.getOrderBy()));
+ return buildPagedResult(result.getRight(), query.getPage(), query.getSize(), result.getLeft());
+ }
+
@Override
- public UserRequestTO start(final String bpmnProcess, final String userKey) {
- return userKey == null
+ public UserRequest start(final String bpmnProcess, final String user) {
+ return user == null
? logic.start(bpmnProcess)
- : logic.start(bpmnProcess, userKey);
+ : logic.start(bpmnProcess, getActualKey(userDAO, user));
}
@Override
@@ -54,14 +70,13 @@ public class UserRequestServiceImpl extends AbstractServiceImpl implements UserR
}
@Override
- public List<UserRequestForm> getForms(final String userKey) {
- return logic.getForms(userKey);
- }
-
- @Override
public PagedResult<UserRequestForm> getForms(final UserRequestFormQuery query) {
+ if (query.getUser() != null) {
+ query.setUser(getActualKey(userDAO, query.getUser()));
+ }
+
Pair<Integer, List<UserRequestForm>> result = logic.getForms(
- query.getPage(), query.getSize(), getOrderByClauses(query.getOrderBy()));
+ query.getUser(), query.getPage(), query.getSize(), getOrderByClauses(query.getOrderBy()));
return buildPagedResult(result.getRight(), query.getPage(), query.getSize(), result.getLeft());
}
@@ -69,5 +84,4 @@ public class UserRequestServiceImpl extends AbstractServiceImpl implements UserR
public UserTO submitForm(final UserRequestForm form) {
return logic.submitForm(form);
}
-
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/fit/core-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index cc8b494..47a142a 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -1541,6 +1541,26 @@ under the License.
<build>
<plugins>
+ <!-- Adds Flowable custom classes -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>add-flowable-custom-classes</id>
+ <phase>initialize</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${basedir}/src/main/java-all</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
<!-- Adds Flowable test content -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/AssignDirectorGroup.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/AssignDirectorGroup.java b/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/AssignDirectorGroup.java
new file mode 100644
index 0000000..4db7ac2
--- /dev/null
+++ b/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/AssignDirectorGroup.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.fit.core.reference.flowable;
+
+import org.apache.syncope.common.lib.patch.MembershipPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.core.flowable.impl.FlowableRuntimeUtils;
+import org.apache.syncope.core.flowable.task.AbstractFlowableServiceTask;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.PropagationByResource;
+import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AssignDirectorGroup extends AbstractFlowableServiceTask {
+
+ @Autowired
+ private UserDataBinder dataBinder;
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Override
+ protected void doExecute(final String executionId) {
+ User user = engine.getRuntimeService().
+ getVariable(executionId, FlowableRuntimeUtils.USER, User.class);
+
+ Boolean secondLevelApprove = engine.getRuntimeService().
+ getVariable(executionId, "secondLevelApprove", Boolean.class);
+ if (Boolean.TRUE.equals(secondLevelApprove)) {
+ user = userDAO.save(user);
+
+ UserPatch userPatch = new UserPatch();
+ userPatch.setKey(user.getKey());
+ userPatch.getMemberships().add(new MembershipPatch.Builder().
+ group("ebf97068-aa4b-4a85-9f01-680e8c4cf227").build());
+
+ PropagationByResource propByRes = dataBinder.update(user, userPatch);
+
+ // report updated user and propagation by resource as result
+ engine.getRuntimeService().setVariable(executionId, FlowableRuntimeUtils.USER, user);
+ engine.getRuntimeService().setVariable(executionId, FlowableRuntimeUtils.PROP_BY_RESOURCE, propByRes);
+ } else {
+ LOG.info("Second level was not approved, not assigning the director group to " + user.getUsername());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/CreateARelationship.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/CreateARelationship.java b/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/CreateARelationship.java
new file mode 100644
index 0000000..b0c5261
--- /dev/null
+++ b/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/CreateARelationship.java
@@ -0,0 +1,71 @@
+/*
+ * 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.fit.core.reference.flowable;
+
+import org.apache.syncope.common.lib.patch.RelationshipPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.RelationshipTO;
+import org.apache.syncope.core.flowable.impl.FlowableRuntimeUtils;
+import org.apache.syncope.core.flowable.task.AbstractFlowableServiceTask;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.PropagationByResource;
+import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class CreateARelationship extends AbstractFlowableServiceTask {
+
+ @Autowired
+ private UserDataBinder dataBinder;
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Override
+ protected void doExecute(final String executionId) {
+ User user = engine.getRuntimeService().
+ getVariable(executionId, FlowableRuntimeUtils.USER, User.class);
+
+ Boolean approve = engine.getRuntimeService().
+ getVariable(executionId, "approve", Boolean.class);
+ if (Boolean.TRUE.equals(approve)) {
+ user = userDAO.save(user);
+
+ String printer = engine.getRuntimeService().
+ getVariable(executionId, "printer", String.class);
+
+ UserPatch userPatch = new UserPatch();
+ userPatch.setKey(user.getKey());
+ userPatch.getRelationships().add(new RelationshipPatch.Builder().
+ relationshipTO(new RelationshipTO.Builder().
+ otherEnd("PRINTER", printer).type("neighborhood").build()).
+ build());
+
+ PropagationByResource propByRes = dataBinder.update(user, userPatch);
+
+ // report updated user and propagation by resource as result
+ engine.getRuntimeService().setVariable(executionId, FlowableRuntimeUtils.USER, user);
+ engine.getRuntimeService().setVariable(executionId, FlowableRuntimeUtils.PROP_BY_RESOURCE, propByRes);
+ } else {
+ LOG.info("Printer assignment to " + user.getUsername() + " was not approved");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/PrintersValueProvider.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/PrintersValueProvider.java b/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/PrintersValueProvider.java
new file mode 100644
index 0000000..82e9693
--- /dev/null
+++ b/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/PrintersValueProvider.java
@@ -0,0 +1,70 @@
+/*
+ * 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.fit.core.reference.flowable;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.flowable.api.DropdownValueProvider;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+public class PrintersValueProvider implements DropdownValueProvider {
+
+ private static final SearchCond PRINTER_COND;
+
+ private static final List<OrderByClause> ORDER_BY;
+
+ static {
+ AnyTypeCond anyTypeCond = new AnyTypeCond();
+ anyTypeCond.setAnyTypeKey("PRINTER");
+ PRINTER_COND = SearchCond.getLeafCond(anyTypeCond);
+
+ OrderByClause orderByNameAsc = new OrderByClause();
+ orderByNameAsc.setField("name");
+ orderByNameAsc.setDirection(OrderByClause.Direction.ASC);
+ ORDER_BY = Collections.singletonList(orderByNameAsc);
+ }
+
+ @Autowired
+ private AnySearchDAO anySearchDAO;
+
+ @Transactional(readOnly = true)
+ @Override
+ public Map<String, String> getValues() {
+ return anySearchDAO.<AnyObject>search(PRINTER_COND, ORDER_BY, AnyTypeKind.ANY_OBJECT).stream().
+ collect(Collectors.toMap(
+ AnyObject::getKey,
+ AnyObject::getName,
+ (u, v) -> {
+ throw new IllegalStateException(String.format("Duplicate key %s", u));
+ },
+ LinkedHashMap::new));
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/AssignDirectorGroup.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/AssignDirectorGroup.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/AssignDirectorGroup.java
deleted file mode 100644
index abdfcb6..0000000
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/AssignDirectorGroup.java
+++ /dev/null
@@ -1,63 +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.fit.core.reference;
-
-import org.apache.syncope.common.lib.patch.MembershipPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.core.flowable.impl.FlowableRuntimeUtils;
-import org.apache.syncope.core.flowable.task.AbstractFlowableServiceTask;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.PropagationByResource;
-import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class AssignDirectorGroup extends AbstractFlowableServiceTask {
-
- @Autowired
- private UserDataBinder dataBinder;
-
- @Autowired
- private UserDAO userDAO;
-
- @Override
- protected void doExecute(final String executionId) {
- User user = engine.getRuntimeService().
- getVariable(executionId, FlowableRuntimeUtils.USER, User.class);
-
- Boolean secondLevelApprove = engine.getRuntimeService().
- getVariable(executionId, "secondLevelApprove", Boolean.class);
- if (Boolean.TRUE.equals(secondLevelApprove)) {
- user = userDAO.save(user);
-
- UserPatch userPatch = new UserPatch();
- userPatch.setKey(user.getKey());
- userPatch.getMemberships().add(new MembershipPatch.Builder().
- group("ebf97068-aa4b-4a85-9f01-680e8c4cf227").build());
-
- PropagationByResource propByRes = dataBinder.update(user, userPatch);
-
- // report updated user and propagation by resource as result
- engine.getRuntimeService().setVariable(executionId, FlowableRuntimeUtils.USER, user);
- engine.getRuntimeService().setVariable(executionId, FlowableRuntimeUtils.PROP_BY_RESOURCE, propByRes);
- } else {
- LOG.info("Second level was not approved, not assigning the director group to " + user.getUsername());
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/fit/core-reference/src/main/resources/all/workflowTestContext.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/all/workflowTestContext.xml b/fit/core-reference/src/main/resources/all/workflowTestContext.xml
index 2329c53..b14490a 100644
--- a/fit/core-reference/src/main/resources/all/workflowTestContext.xml
+++ b/fit/core-reference/src/main/resources/all/workflowTestContext.xml
@@ -19,9 +19,12 @@ under the License.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context.xsd">
- <bean id="assignDirectorGroup" class="org.apache.syncope.fit.core.reference.AssignDirectorGroup"/>
+ <context:component-scan base-package="org.apache.syncope.fit.core.reference.flowable"/>
</beans>
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/fit/core-reference/src/main/resources/assignPrinterRequest.bpmn20.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/assignPrinterRequest.bpmn20.xml b/fit/core-reference/src/main/resources/assignPrinterRequest.bpmn20.xml
new file mode 100644
index 0000000..c9ecb9c
--- /dev/null
+++ b/fit/core-reference/src/main/resources/assignPrinterRequest.bpmn20.xml
@@ -0,0 +1,92 @@
+<?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:flowable="http://flowable.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://www.flowable.org/processdef">
+
+ <process id="assignPrinterRequest" name="Assign printer" isExecutable="true">
+ <startEvent id="startevent1" name="Start"/>
+ <endEvent id="endevent1" name="End"/>
+ <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="selectPrinter"/>
+ <userTask id="selectPrinter" name="Select printer" flowable:formKey="selectPrinter" flowable:assignee="${wfExecutor}">
+ <extensionElements>
+ <flowable:formProperty id="printer" name="Printer" variable="printer" type="dropdown" required="true">
+ <flowable:value id="dropdownValueProvider" name="printersValueProvider"/>
+ </flowable:formProperty>
+ <flowable:formProperty id="printMode" name="Preferred print mode?" type="enum">
+ <flowable:value id="bw" name="Black / White"/>
+ <flowable:value id="color" name="Color"/>
+ </flowable:formProperty>
+ </extensionElements>
+ </userTask>
+ <userTask id="approvePrinter" name="Approve printer" flowable:formKey="approvePrinter">
+ <extensionElements>
+ <flowable:formProperty id="username" name="Username" type="string" expression="${userTO.username}" writable="false"/>
+ <flowable:formProperty id="printer" name="Selected printer" type="string" expression="${printer}" writable="false"/>
+ <flowable:formProperty id="approve" name="Approve?" type="boolean" variable="approve" required="true"/>
+ </extensionElements>
+ </userTask>
+ <sequenceFlow id="sid-D7047714-8E57-46B8-B6D4-4844DE330329" sourceRef="selectPrinter" targetRef="approvePrinter"/>
+ <serviceTask id="createARelationship" name="Create ARelationship" flowable:expression="#{createARelationship.execute(execution.processInstanceId)}"/>
+ <sequenceFlow id="sid-33880AE7-35C6-4A39-8E5B-12D8BA53F042" sourceRef="approvePrinter" targetRef="createARelationship"/>
+ <sequenceFlow id="sid-831E1896-EDF9-4F7D-AA42-E86CC1F8C5D3" sourceRef="createARelationship" targetRef="endevent1"/>
+ </process>
+ <bpmndi:BPMNDiagram id="BPMNDiagram_assignPrinterRequest">
+ <bpmndi:BPMNPlane bpmnElement="assignPrinterRequest" id="BPMNPlane_assignPrinterRequest">
+ <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
+ <omgdc:Bounds height="30.0" width="30.0" x="180.0" y="115.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
+ <omgdc:Bounds height="28.0" width="28.0" x="885.0" y="116.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="selectPrinter" id="BPMNShape_selectPrinter">
+ <omgdc:Bounds height="80.0" width="100.0" x="330.0" y="90.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="approvePrinter" id="BPMNShape_approvePrinter">
+ <omgdc:Bounds height="80.0" width="100.0" x="495.5" y="90.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="createARelationship" id="BPMNShape_createARelationship">
+ <omgdc:Bounds height="80.0" width="100.0" x="675.0" y="90.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
+ <omgdi:waypoint x="209.94999901196195" y="130.0"/>
+ <omgdi:waypoint x="330.0" y="130.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="sid-D7047714-8E57-46B8-B6D4-4844DE330329" id="BPMNEdge_sid-D7047714-8E57-46B8-B6D4-4844DE330329">
+ <omgdi:waypoint x="429.95000000000005" y="130.0"/>
+ <omgdi:waypoint x="495.5" y="130.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="sid-33880AE7-35C6-4A39-8E5B-12D8BA53F042" id="BPMNEdge_sid-33880AE7-35C6-4A39-8E5B-12D8BA53F042">
+ <omgdi:waypoint x="595.4499999999068" y="130.0"/>
+ <omgdi:waypoint x="675.0" y="130.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="sid-831E1896-EDF9-4F7D-AA42-E86CC1F8C5D3" id="BPMNEdge_sid-831E1896-EDF9-4F7D-AA42-E86CC1F8C5D3">
+ <omgdi:waypoint x="774.9499999999266" y="130.0"/>
+ <omgdi:waypoint x="885.0" y="130.0"/>
+ </bpmndi:BPMNEdge>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+</definitions>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
index e2f351b..cbdb19b 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
@@ -66,6 +66,7 @@ import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.syncope.common.lib.types.StatusPatchType;
import org.apache.syncope.common.rest.api.RESTHeaders;
import org.apache.syncope.common.rest.api.beans.AnyQuery;
+import org.apache.syncope.common.rest.api.beans.UserRequestFormQuery;
import org.apache.syncope.common.rest.api.service.AnyObjectService;
import org.apache.syncope.common.rest.api.service.SchemaService;
import org.apache.syncope.common.rest.api.service.UserService;
@@ -495,7 +496,8 @@ public class AuthenticationITCase extends AbstractITCase {
}
// 3. approve user
- UserRequestForm form = userRequestService.getForms(userTO.getKey()).get(0);
+ UserRequestForm form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(userTO.getKey()).build()).getResult().get(0);
form = userRequestService.claimForm(form.getTaskId());
form.getProperty("approveCreate").get().setValue(Boolean.TRUE.toString());
userTO = userRequestService.submitForm(form);
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/fit/core-reference/src/test/java/org/apache/syncope/fit/core/BpmnProcessITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/BpmnProcessITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/BpmnProcessITCase.java
index 443cd83..21fb4fd 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/BpmnProcessITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/BpmnProcessITCase.java
@@ -28,7 +28,7 @@ import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import javax.ws.rs.core.Response;
import org.apache.commons.io.IOUtils;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.fit.AbstractITCase;
import org.apache.syncope.fit.FlowableDetector;
import org.junit.jupiter.api.BeforeAll;
@@ -42,7 +42,7 @@ public class BpmnProcessITCase extends AbstractITCase {
public static void findDefault() {
assumeTrue(FlowableDetector.isFlowableEnabledForUserWorkflow(syncopeService));
bpmnProcessService.list().stream().
- filter(BpmnProcessTO::isUserWorkflow).findAny().
+ filter(BpmnProcess::isUserWorkflow).findAny().
ifPresent(process -> {
userWorkflowKey = process.getKey();
});
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserRequestITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserRequestITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserRequestITCase.java
index 5446894..9281bce 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserRequestITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserRequestITCase.java
@@ -25,14 +25,19 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import java.io.IOException;
+import java.util.List;
import javax.ws.rs.core.MediaType;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.syncope.client.lib.SyncopeClient;
import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.RelationshipTO;
import org.apache.syncope.common.lib.to.UserRequestForm;
-import org.apache.syncope.common.lib.to.UserRequestTO;
+import org.apache.syncope.common.lib.to.UserRequest;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.rest.api.beans.UserRequestFormQuery;
+import org.apache.syncope.common.rest.api.beans.UserRequestQuery;
+import org.apache.syncope.common.rest.api.service.UserRequestService;
import org.apache.syncope.fit.AbstractITCase;
import org.apache.syncope.fit.FlowableDetector;
import org.junit.jupiter.api.BeforeAll;
@@ -42,9 +47,13 @@ public class UserRequestITCase extends AbstractITCase {
@BeforeAll
public static void loadBpmnProcesses() throws IOException {
+ assumeTrue(FlowableDetector.isFlowableEnabledForUserWorkflow(syncopeService));
+
WebClient.client(bpmnProcessService).type(MediaType.APPLICATION_XML_TYPE);
bpmnProcessService.set("directorGroupRequest",
IOUtils.toString(UserRequestITCase.class.getResourceAsStream("/directorGroupRequest.bpmn20.xml")));
+ bpmnProcessService.set("assignPrinterRequest",
+ IOUtils.toString(UserRequestITCase.class.getResourceAsStream("/assignPrinterRequest.bpmn20.xml")));
}
@Test
@@ -56,17 +65,29 @@ public class UserRequestITCase extends AbstractITCase {
assertFalse(user.getMembership("ebf97068-aa4b-4a85-9f01-680e8c4cf227").isPresent());
// start request
- UserRequestTO req = userRequestService.start("directorGroupRequest", user.getKey());
+ UserRequest req = userRequestService.start("directorGroupRequest", user.getKey());
assertNotNull(req);
+ assertEquals("directorGroupRequest", req.getBpmnProcess());
+ assertNotNull(req.getExecutionId());
+ assertEquals(req.getUser(), user.getKey());
+
+ // check that user can see the ongoing request
+ SyncopeClient client = clientFactory.create(user.getUsername(), "password123");
+ PagedResult<UserRequest> requests = client.getService(UserRequestService.class).
+ list(new UserRequestQuery.Builder().user(user.getKey()).build());
+ assertEquals(1, requests.getTotalCount());
+ assertEquals("directorGroupRequest", requests.getResult().get(0).getBpmnProcess());
// 1st approval -> reject
- UserRequestForm form = userRequestService.getForms(user.getKey()).get(0);
+ UserRequestForm form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().get(0);
form = userRequestService.claimForm(form.getTaskId());
form.getProperty("firstLevelApprove").get().setValue(Boolean.FALSE.toString());
userRequestService.submitForm(form);
// no more forms, group not assigned
- assertTrue(userRequestService.getForms(user.getKey()).isEmpty());
+ assertTrue(userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().isEmpty());
assertFalse(userService.read(user.getKey()).getMembership("ebf97068-aa4b-4a85-9f01-680e8c4cf227").isPresent());
// start request again
@@ -74,19 +95,22 @@ public class UserRequestITCase extends AbstractITCase {
assertNotNull(req);
// 1st approval -> accept
- form = userRequestService.getForms(user.getKey()).get(0);
+ form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().get(0);
form = userRequestService.claimForm(form.getTaskId());
form.getProperty("firstLevelApprove").get().setValue(Boolean.TRUE.toString());
userRequestService.submitForm(form);
// 2nd approval -> reject
- form = userRequestService.getForms(user.getKey()).get(0);
+ form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().get(0);
form = userRequestService.claimForm(form.getTaskId());
form.getProperty("secondLevelApprove").get().setValue(Boolean.FALSE.toString());
user = userRequestService.submitForm(form);
// no more forms, group not assigned
- assertTrue(userRequestService.getForms(user.getKey()).isEmpty());
+ assertTrue(userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().isEmpty());
assertFalse(userService.read(user.getKey()).getMembership("ebf97068-aa4b-4a85-9f01-680e8c4cf227").isPresent());
// start request again
@@ -94,13 +118,15 @@ public class UserRequestITCase extends AbstractITCase {
assertNotNull(req);
// 1st approval -> accept
- form = userRequestService.getForms(user.getKey()).get(0);
+ form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().get(0);
form = userRequestService.claimForm(form.getTaskId());
form.getProperty("firstLevelApprove").get().setValue(Boolean.TRUE.toString());
userRequestService.submitForm(form);
// 2nd approval -> accept
- form = userRequestService.getForms(user.getKey()).get(0);
+ form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().get(0);
form = userRequestService.claimForm(form.getTaskId());
form.getProperty("secondLevelApprove").get().setValue(Boolean.TRUE.toString());
user = userRequestService.submitForm(form);
@@ -115,7 +141,7 @@ public class UserRequestITCase extends AbstractITCase {
assumeTrue(FlowableDetector.isFlowableEnabledForUserWorkflow(syncopeService));
PagedResult<UserRequestForm> forms =
- userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build());
+ userRequestService.getForms(new UserRequestFormQuery.Builder().build());
int preForms = forms.getTotalCount();
UserTO user = createUser(UserITCase.getUniqueSampleTO("twoLevelsApproval@tirasa.net")).getEntity();
@@ -123,22 +149,101 @@ public class UserRequestITCase extends AbstractITCase {
assertFalse(user.getMembership("ebf97068-aa4b-4a85-9f01-680e8c4cf227").isPresent());
// start request
- UserRequestTO req = userRequestService.start("directorGroupRequest", user.getKey());
+ UserRequest req = userRequestService.start("directorGroupRequest", user.getKey());
assertNotNull(req);
// check that form was generated
- forms = userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build());
+ forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
assertEquals(preForms + 1, forms.getTotalCount());
- assertEquals(1, userRequestService.getForms(user.getKey()).size());
+ assertEquals(1, userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().size());
// cancel request
userRequestService.cancel(req.getExecutionId(), "nothing in particular");
// check that form was removed
- forms = userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build());
+ forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
+ assertEquals(preForms, forms.getTotalCount());
+
+ assertTrue(userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().isEmpty());
+ }
+
+ @Test
+ public void userSelection() {
+ assumeTrue(FlowableDetector.isFlowableEnabledForUserWorkflow(syncopeService));
+
+ assumeTrue(FlowableDetector.isFlowableEnabledForUserWorkflow(syncopeService));
+
+ PagedResult<UserRequestForm> forms =
+ userRequestService.getForms(new UserRequestFormQuery.Builder().build());
+ int preForms = forms.getTotalCount();
+
+ UserTO user = createUser(UserITCase.getUniqueSampleTO("userSelection@tirasa.net")).getEntity();
+ assertNotNull(user);
+ List<RelationshipTO> relationships = userService.read(user.getKey()).getRelationships();
+ assertTrue(relationships.isEmpty());
+
+ SyncopeClient client = clientFactory.create(user.getUsername(), "password123");
+
+ // start request as user
+ UserRequest req = client.getService(UserRequestService.class).start("assignPrinterRequest", null);
+ assertNotNull(req);
+
+ // check (as admin) that a new form is available
+ forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
+ assertEquals(preForms + 1, forms.getTotalCount());
+
+ // get (as user) the form, claim and submit
+ PagedResult<UserRequestForm> userForms = client.getService(UserRequestService.class).
+ getForms(new UserRequestFormQuery.Builder().user(user.getKey()).build());
+ assertEquals(1, userForms.getTotalCount());
+
+ UserRequestForm form = userForms.getResult().get(0);
+ assertEquals("assignPrinterRequest", form.getBpmnProcess());
+ form = client.getService(UserRequestService.class).claimForm(form.getTaskId());
+
+ assertFalse(form.getProperty("printer").get().getDropdownValues().isEmpty());
+ form.getProperty("printer").ifPresent(printer -> printer.setValue("8559d14d-58c2-46eb-a2d4-a7d35161e8f8"));
+
+ assertFalse(form.getProperty("printMode").get().getEnumValues().isEmpty());
+ form.getProperty("printMode").ifPresent(printMode -> printMode.setValue("color"));
+
+ client.getService(UserRequestService.class).submitForm(form);
+
+ userForms = client.getService(UserRequestService.class).getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build());
+ assertEquals(0, userForms.getTotalCount());
+
+ // check that user can see the ongoing request
+ PagedResult<UserRequest> requests = client.getService(UserRequestService.class).
+ list(new UserRequestQuery.Builder().user(user.getKey()).build());
+ assertEquals(1, requests.getTotalCount());
+ assertEquals("assignPrinterRequest", requests.getResult().get(0).getBpmnProcess());
+
+ // get (as admin) the new form, claim and submit
+ form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().get(0);
+ assertEquals("assignPrinterRequest", form.getBpmnProcess());
+ form = userRequestService.claimForm(form.getTaskId());
+
+ assertEquals("8559d14d-58c2-46eb-a2d4-a7d35161e8f8", form.getProperty("printer").get().getValue());
+
+ form.getProperty("approve").get().setValue(Boolean.TRUE.toString());
+ userRequestService.submitForm(form);
+
+ // no more forms available
+ forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
assertEquals(preForms, forms.getTotalCount());
- assertTrue(userRequestService.getForms(user.getKey()).isEmpty());
+ assertTrue(client.getService(UserRequestService.class).
+ list(new UserRequestQuery.Builder().user(user.getKey()).build()).getResult().isEmpty());
+
+ // check that relationship was made effective by approval
+ relationships = userService.read(user.getKey()).getRelationships();
+ assertFalse(relationships.isEmpty());
+ assertTrue(relationships.stream().
+ anyMatch(relationship -> "8559d14d-58c2-46eb-a2d4-a7d35161e8f8".equals(relationship.getOtherEndKey())));
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java
index 0e48cf2..63db20e 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java
@@ -130,7 +130,8 @@ public class UserSelfITCase extends AbstractITCase {
}
// now approve and verify that propagation has happened
- UserRequestForm form = userRequestService.getForms(userTO.getKey()).get(0);
+ UserRequestForm form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(userTO.getKey()).build()).getResult().get(0);
form = userRequestService.claimForm(form.getTaskId());
form.getProperty("approveCreate").get().setValue(Boolean.TRUE.toString());
userTO = userRequestService.submitForm(form);
@@ -228,7 +229,8 @@ public class UserSelfITCase extends AbstractITCase {
}
// 3. approve self-update as admin
- UserRequestForm form = userRequestService.getForms(updated.getKey()).get(0);
+ UserRequestForm form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(updated.getKey()).build()).getResult().get(0);
form = userRequestService.claimForm(form.getTaskId());
form.getProperty("approveUpdate").get().setValue(Boolean.TRUE.toString());
updated = userRequestService.submitForm(form);
@@ -420,7 +422,8 @@ public class UserSelfITCase extends AbstractITCase {
assertEquals("createApproval", userTO.getStatus());
// 2. request if there is any pending task for user just created
- UserRequestForm form = userRequestService.getForms(userTO.getKey()).get(0);
+ UserRequestForm form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(userTO.getKey()).build()).getResult().get(0);
assertNotNull(form);
assertNotNull(form.getUsername());
assertEquals(userTO.getUsername(), form.getUsername());
@@ -480,8 +483,7 @@ public class UserSelfITCase extends AbstractITCase {
assumeTrue(FlowableDetector.isFlowableEnabledForUserWorkflow(syncopeService));
// read forms *before* any operation
- PagedResult<UserRequestForm> forms =
- userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build());
+ PagedResult<UserRequestForm> forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
int preForms = forms.getTotalCount();
UserTO userTO = UserITCase.getUniqueSampleTO("createWithApproval@syncope.apache.org");
@@ -514,7 +516,7 @@ public class UserSelfITCase extends AbstractITCase {
assertNotNull(exception);
// 2. request if there is any pending form for user just created
- forms = userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build());
+ forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
assertEquals(preForms + 1, forms.getTotalCount());
// 3. as admin, update user: still pending approval
@@ -524,7 +526,8 @@ public class UserSelfITCase extends AbstractITCase {
userPatch.setUsername(new StringReplacePatchItem.Builder().value(updatedUsername).build());
updateUser(userPatch);
- UserRequestForm form = userRequestService.getForms(userTO.getKey()).get(0);
+ UserRequestForm form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(userTO.getKey()).build()).getResult().get(0);
assertNotNull(form);
assertNotNull(form.getTaskId());
assertNotNull(form.getUserTO());
@@ -567,8 +570,8 @@ public class UserSelfITCase extends AbstractITCase {
assumeTrue(FlowableDetector.isFlowableEnabledForUserWorkflow(syncopeService));
// read forms *before* any operation
- PagedResult<UserRequestForm> forms = userRequestService.getForms(new UserRequestFormQuery.Builder().
- page(1).size(1000).build());
+ PagedResult<UserRequestForm> forms = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().build());
int preForms = forms.getTotalCount();
UserTO created = createUser(UserITCase.getUniqueSampleTO("updateApproval@syncope.apache.org")).getEntity();
@@ -585,10 +588,11 @@ public class UserSelfITCase extends AbstractITCase {
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
assertEquals("updateApproval", userService.read(created.getKey()).getStatus());
- forms = userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build());
+ forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
assertEquals(preForms + 1, forms.getTotalCount());
- UserRequestForm form = userRequestService.getForms(created.getKey()).get(0);
+ UserRequestForm form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(created.getKey()).build()).getResult().get(0);
assertNotNull(form);
assertNotNull(form.getTaskId());
assertNull(form.getOwner());
@@ -607,7 +611,8 @@ public class UserSelfITCase extends AbstractITCase {
assertEquals(0, updated.getMemberships().size());
// the patch is not updated in the approval form
- form = userRequestService.getForms(created.getKey()).get(0);
+ form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(created.getKey()).build()).getResult().get(0);
assertEquals(patch, form.getUserPatch());
// approve the user
@@ -642,8 +647,7 @@ public class UserSelfITCase extends AbstractITCase {
assumeTrue(FlowableDetector.isFlowableEnabledForUserWorkflow(syncopeService));
// read forms *before* any operation
- PagedResult<UserRequestForm> forms = userRequestService.getForms(new UserRequestFormQuery.Builder().
- page(1).size(1000).build());
+ PagedResult<UserRequestForm> forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
int preForms = forms.getTotalCount();
UserTO userTO = UserITCase.getUniqueSampleTO("issueSYNCOPE15@syncope.apache.org");
@@ -667,10 +671,11 @@ public class UserSelfITCase extends AbstractITCase {
assertEquals(userTO.getCreationDate(), userTO.getLastChangeDate());
// 2. request if there is any pending form for user just created
- forms = userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build());
+ forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
assertEquals(preForms + 1, forms.getTotalCount());
- UserRequestForm form = userRequestService.getForms(userTO.getKey()).get(0);
+ UserRequestForm form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(userTO.getKey()).build()).getResult().get(0);
assertNotNull(form);
// 3. first claim by bellini ....
@@ -692,12 +697,12 @@ public class UserSelfITCase extends AbstractITCase {
userTO = userRequestService.submitForm(form);
assertNotNull(userTO);
assertEquals(preForms,
- userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build()).
- getTotalCount());
- assertTrue(userRequestService.getForms(userTO.getKey()).isEmpty());
+ userRequestService.getForms(new UserRequestFormQuery.Builder().build()).getTotalCount());
+ assertTrue(userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(userTO.getKey()).build()).getResult().isEmpty());
// 7.check that no more forms are still to be processed
- forms = userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build());
+ forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
assertEquals(preForms, forms.getTotalCount());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index b4c82ae..db39a89 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1748,6 +1748,12 @@ under the License.
</plugin>
<plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>3.0.0</version>
+ </plugin>
+
+ <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
@@ -2305,8 +2311,8 @@ under the License.
<link>https://docs.spring.io/spring-security/site/docs/5.0.x/api/</link>
<link>http://www.flowable.org/docs/javadocs/</link>
<link>https://build.shibboleth.net/nexus/content/sites/site/java-opensaml/3.3.0/apidocs/</link>
- <link>https://artifacts.elastic.co/javadoc/org/elasticsearch/elasticsearch/6.4.1/index.html</link>
- <link>http://docs.swagger.io/swagger-core/v2.0.5/apidocs/</link>
+ <link>https://artifacts.elastic.co/javadoc/org/elasticsearch/elasticsearch/6.4.1/index.html</link>
+ <link>http://docs.swagger.io/swagger-core/v2.0.5/apidocs/</link>
</links>
</configuration>
<reportSets>
[6/6] syncope git commit: [SYNCOPE-1369] User requests forms now
support dropdowns - via Flowable customization
Posted by il...@apache.org.
[SYNCOPE-1369] User requests forms now support dropdowns - via Flowable customization
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/fee1317d
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/fee1317d
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/fee1317d
Branch: refs/heads/master
Commit: fee1317dc3e32d89fcbab5f5e748f49ce5e04f83
Parents: fba9bce
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Oct 2 14:31:40 2018 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue Oct 2 14:32:07 2018 +0200
----------------------------------------------------------------------
.../console/commons/MapChoiceRenderer.java | 21 +-
.../html/form/AjaxDropDownChoicePanel.java | 3 +-
.../console/wizards/any/Relationships.java | 5 +-
.../wizards/any/Relationships.properties | 3 +
.../wizards/any/Relationships_it.properties | 3 +
.../wizards/any/Relationships_ja.properties | 3 +
.../wizards/any/Relationships_pt_BR.properties | 3 +
.../wizards/any/Relationships_ru.properties | 3 +
.../syncope/common/lib/to/RelationshipTO.java | 16 +
.../core/persistence/api/dao/AnyObjectDAO.java | 2 +-
.../persistence/jpa/dao/JPAAnyObjectDAO.java | 12 +-
.../test/resources/domains/MasterContent.xml | 6 +-
.../provisioning/java/MappingManagerImpl.java | 47 +--
.../java/data/AbstractAnyDataBinder.java | 5 +-
.../java/data/AnyObjectDataBinderImpl.java | 11 +-
.../java/data/UserDataBinderImpl.java | 7 +-
ext/flowable/client-console/pom.xml | 32 +-
.../client/console/approvals/Approval.java | 29 +-
.../approvals/ApprovalDirectoryPanel.java | 19 +-
.../syncope/client/console/pages/Flowable.java | 4 +-
.../panels/BpmnProcessDirectoryPanel.java | 48 +--
.../resources/AbstractBpmnProcessResource.java | 6 +-
.../resources/BpmnProcessGETResource.java | 4 +-
.../resources/BpmnProcessPUTResource.java | 4 +-
.../console/rest/BpmnProcessRestClient.java | 4 +-
.../console/rest/UserRequestRestClient.java | 11 +-
.../client/console/widgets/ApprovalsWidget.java | 10 +-
.../src/main/resources/dropdown.diff | 139 ++++++++
.../client/console/pages/Approvals.properties | 2 +-
.../console/pages/Approvals_it.properties | 2 +-
.../console/pages/Approvals_ja.properties | 2 +-
.../console/pages/Approvals_pt_BR.properties | 2 +-
.../console/pages/Approvals_ru.properties | 2 +-
.../syncope/common/lib/to/BpmnProcess.java | 72 ++++
.../syncope/common/lib/to/BpmnProcessTO.java | 72 ----
.../syncope/common/lib/to/UserRequest.java | 70 ++++
.../syncope/common/lib/to/UserRequestForm.java | 26 +-
.../common/lib/to/UserRequestFormProperty.java | 8 +
.../syncope/common/lib/to/UserRequestTO.java | 70 ----
.../common/lib/types/FlowableEntitlement.java | 14 +-
.../lib/types/UserRequestFormPropertyType.java | 3 +-
.../core/flowable/api/BpmnProcessManager.java | 4 +-
.../flowable/api/DropdownValueProvider.java | 31 ++
.../core/flowable/api/UserRequestHandler.java | 30 +-
.../impl/FlowableBpmnProcessManager.java | 9 +-
.../flowable/impl/FlowableRuntimeUtils.java | 50 +--
.../impl/FlowableUserRequestHandler.java | 345 ++++++++++++-------
.../support/DomainProcessEngineFactoryBean.java | 6 +
.../support/DropdownAwareJsonConverter.java | 31 ++
.../DropdownAwareUserTaskJsonConverter.java | 98 ++++++
.../core/flowable/support/DropdownFormType.java | 59 ++++
.../support/SyncopeFormHandlerHelper.java | 56 +++
.../support/SyncopeTaskFormHandler.java | 112 ++++++
.../main/resources/workflowFlowableContext.xml | 4 +
.../syncope/core/logic/BpmnProcessLogic.java | 8 +-
.../syncope/core/logic/UserRequestLogic.java | 115 +++++--
.../rest/api/beans/UserRequestFormQuery.java | 18 +
.../common/rest/api/beans/UserRequestQuery.java | 50 +++
.../rest/api/service/BpmnProcessService.java | 20 +-
.../rest/api/service/UserRequestService.java | 73 ++--
.../api/service/UserWorkflowTaskService.java | 14 +
.../cxf/service/BpmnProcessServiceImpl.java | 4 +-
.../cxf/service/UserRequestServiceImpl.java | 38 +-
fit/core-reference/pom.xml | 20 ++
.../reference/flowable/AssignDirectorGroup.java | 65 ++++
.../reference/flowable/CreateARelationship.java | 71 ++++
.../flowable/PrintersValueProvider.java | 70 ++++
.../fit/core/reference/AssignDirectorGroup.java | 63 ----
.../main/resources/all/workflowTestContext.xml | 7 +-
.../resources/assignPrinterRequest.bpmn20.xml | 92 +++++
.../syncope/fit/core/AuthenticationITCase.java | 4 +-
.../syncope/fit/core/BpmnProcessITCase.java | 4 +-
.../syncope/fit/core/UserRequestITCase.java | 135 +++++++-
.../apache/syncope/fit/core/UserSelfITCase.java | 45 +--
pom.xml | 10 +-
75 files changed, 1909 insertions(+), 657 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/client/console/src/main/java/org/apache/syncope/client/console/commons/MapChoiceRenderer.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/MapChoiceRenderer.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/MapChoiceRenderer.java
index 2845105..92d060d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/MapChoiceRenderer.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/MapChoiceRenderer.java
@@ -23,33 +23,28 @@ import java.util.Map;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.model.IModel;
-public class MapChoiceRenderer<T, K> implements IChoiceRenderer<T> {
+public class MapChoiceRenderer implements IChoiceRenderer<String> {
private static final long serialVersionUID = -7452881117778186644L;
- private final Map<T, K> map;
+ private final Map<String, String> map;
- public MapChoiceRenderer(final Map<T, K> map) {
+ public MapChoiceRenderer(final Map<String, String> map) {
this.map = map;
}
@Override
- public Object getDisplayValue(final T key) {
+ public Object getDisplayValue(final String key) {
return map.get(key);
}
@Override
- public String getIdValue(final T key, final int index) {
- return key.toString();
+ public String getIdValue(final String key, final int index) {
+ return key;
}
@Override
- public T getObject(final String id, final IModel<? extends List<? extends T>> choices) {
- for (Map.Entry<T, K> entry : map.entrySet()) {
- if (entry.getValue() != null && entry.getValue().toString().equals(id)) {
- return entry.getKey();
- }
- }
- return null;
+ public String getObject(final String id, final IModel<? extends List<? extends String>> choices) {
+ return id;
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.java
index 193c0ad..c52efac 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.java
@@ -44,8 +44,7 @@ public class AjaxDropDownChoicePanel<T extends Serializable> extends FieldPanel<
super(id, name, model);
- field = new BootstrapSelect<>(
- "dropDownChoiceField", model, Collections.<T>emptyList(), new ChoiceRenderer<>());
+ field = new BootstrapSelect<>("dropDownChoiceField", model, Collections.<T>emptyList(), new ChoiceRenderer<>());
add(field.setLabel(new Model<>(name)).setOutputMarkupId(true));
if (enableOnBlur) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
index 06e126b..bfbdc1d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
@@ -136,14 +136,13 @@ public class Relationships extends WizardStep implements ICondition {
public Panel getPanel(final String panelId) {
return new ListViewPanel.Builder<>(RelationshipTO.class, pageRef).
setItems(relationships.get(relationship)).
- includes("otherEndType", "otherEndKey").
+ includes("otherEndType", "otherEndKey", "otherEndName").
addAction(new ActionLink<RelationshipTO>() {
private static final long serialVersionUID = -6847033126124401556L;
@Override
- public void onClick(
- final AjaxRequestTarget target, final RelationshipTO modelObject) {
+ public void onClick(final AjaxRequestTarget target, final RelationshipTO modelObject) {
removeRelationships(relationships, modelObject);
send(Relationships.this, Broadcast.DEPTH, new ListViewReload<>(target));
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships.properties
index cfefe54..45e8a78 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships.properties
@@ -16,3 +16,6 @@
# under the License.
relationships.empty.list=No relationships defined
any.relationships=Relationships
+otherEndType=AnyType
+otherEndKey=Key
+otherEndName=Name
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_it.properties
index 5260a62..cdc900f 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_it.properties
@@ -16,3 +16,6 @@
# under the License.
relationships.empty.list=Nessuna relazione specificata
any.relationships=Relazioni
+otherEndType=AnyType
+otherEndKey=Chiave
+otherEndName=Nome
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ja.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ja.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ja.properties
index c0f26ae..5561099 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ja.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ja.properties
@@ -16,3 +16,6 @@
# under the License.
relationships.empty.list=\u95a2\u4fc2\u306f\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u307e\u305b\u3093
any.relationships=\u95a2\u4fc2
+otherEndType=AnyType
+otherEndKey=Key
+otherEndName=Name
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_pt_BR.properties
index 44f4ac8..c0c71dc 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_pt_BR.properties
@@ -16,3 +16,6 @@
# under the License.
relationships.empty.list=N\u00e3o h\u00e1 relacionamentos definidos
any.relationships=Relationships
+otherEndType=AnyType
+otherEndKey=Key
+otherEndName=Name
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ru.properties
index 93a15fb..9fcb63a 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ru.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ru.properties
@@ -17,3 +17,6 @@
relationships.empty.list=\u0421\u0432\u044f\u0437\u0438 \u043d\u0435 \u0437\u0430\u0434\u0430\u043d\u044b
any.relationships=\u0421\u0432\u044f\u0437\u0438
+otherEndType=AnyType
+otherEndKey=Key
+otherEndName=Name
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTO.java
index 015e18c..06dbd0d 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTO.java
@@ -43,6 +43,13 @@ public class RelationshipTO extends AbstractBaseBean {
return this;
}
+ public Builder otherEnd(final String otherEndType, final String otherEndKey, final String otherEndName) {
+ instance.setOtherEndType(otherEndType);
+ instance.setOtherEndKey(otherEndKey);
+ instance.setOtherEndName(otherEndName);
+ return this;
+ }
+
public RelationshipTO build() {
return instance;
}
@@ -54,6 +61,8 @@ public class RelationshipTO extends AbstractBaseBean {
private String otherEndKey;
+ private String otherEndName;
+
public String getType() {
return type;
}
@@ -78,4 +87,11 @@ public class RelationshipTO extends AbstractBaseBean {
this.otherEndKey = otherEndKey;
}
+ public String getOtherEndName() {
+ return otherEndName;
+ }
+
+ public void setOtherEndName(final String otherEndName) {
+ this.otherEndName = otherEndName;
+ }
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
index f001204..f8f05f9 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
@@ -46,7 +46,7 @@ public interface AnyObjectDAO extends AnyDAO<AnyObject> {
List<Group> findDynGroups(String key);
- List<Relationship<Any<?>, Any<?>>> findAllRelationships(AnyObject anyObject);
+ List<Relationship<Any<?>, AnyObject>> findAllRelationships(AnyObject anyObject);
Collection<Group> findAllGroups(AnyObject anyObject);
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index 4d8aaea..a7211de 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -168,20 +168,20 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
}
@Override
- public List<Relationship<Any<?>, Any<?>>> findAllRelationships(final AnyObject anyObject) {
- List<Relationship<Any<?>, Any<?>>> result = new ArrayList<>();
+ public List<Relationship<Any<?>, AnyObject>> findAllRelationships(final AnyObject anyObject) {
+ List<Relationship<Any<?>, AnyObject>> result = new ArrayList<>();
@SuppressWarnings("unchecked")
- TypedQuery<Relationship<Any<?>, Any<?>>> aquery =
- (TypedQuery<Relationship<Any<?>, Any<?>>>) entityManager().createQuery(
+ TypedQuery<Relationship<Any<?>, AnyObject>> aquery =
+ (TypedQuery<Relationship<Any<?>, AnyObject>>) entityManager().createQuery(
"SELECT e FROM " + JPAARelationship.class.getSimpleName()
+ " e WHERE e.rightEnd=:anyObject OR e.leftEnd=:anyObject");
aquery.setParameter("anyObject", anyObject);
result.addAll(aquery.getResultList());
@SuppressWarnings("unchecked")
- TypedQuery<Relationship<Any<?>, Any<?>>> uquery =
- (TypedQuery<Relationship<Any<?>, Any<?>>>) entityManager().createQuery(
+ TypedQuery<Relationship<Any<?>, AnyObject>> uquery =
+ (TypedQuery<Relationship<Any<?>, AnyObject>>) entityManager().createQuery(
"SELECT e FROM " + JPAURelationship.class.getSimpleName()
+ " e WHERE e.rightEnd=:anyObject");
uquery.setParameter("anyObject", anyObject);
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index fb05d94..5a41085 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -253,14 +253,14 @@ under the License.
<SyncopeRole_entitlements entitlement="ANYTYPE_READ" role_id="User manager"/>
<SyncopeRole_entitlements entitlement="ANYTYPECLASS_LIST" role_id="User manager"/>
<SyncopeRole_entitlements entitlement="ANYTYPECLASS_READ" role_id="User manager"/>
- <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_CLAIM" role_id="User manager"/>
- <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_SUBMIT" role_id="User manager"/>
+ <SyncopeRole_entitlements entitlement="USER_REQUEST_FORM_CLAIM" role_id="User manager"/>
+ <SyncopeRole_entitlements entitlement="USER_REQUEST_FORM_SUBMIT" role_id="User manager"/>
<SyncopeRole_Realm role_id="User manager" realm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"/>
<SyncopeRole id="Other"/>
<SyncopeRole_entitlements entitlement="SCHEMA_READ" role_id="Other"/>
<SyncopeRole_entitlements entitlement="GROUP_READ" role_id="Other"/>
- <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_CLAIM" role_id="Other"/>
+ <SyncopeRole_entitlements entitlement="USER_REQUEST_FORM_CLAIM" role_id="Other"/>
<SyncopeRole_Realm role_id="Other" realm_id="722f3d84-9c2b-4525-8f6e-e4b82c55a36c"/>
<SyncopeRole_Privilege role_id="Other" privilege_id="postMighty"/>
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
index b6c63e3..33077fe 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
@@ -770,11 +770,14 @@ public class MappingManagerImpl implements MappingManager {
default:
}
} else if (intAttrName.getSchemaType() != null && attr != null) {
- GroupableRelatableTO groupableTO = null;
- Group group = null;
+ GroupableRelatableTO groupableTO;
+ Group group;
if (anyTO instanceof GroupableRelatableTO && intAttrName.getMembershipOfGroup() != null) {
groupableTO = (GroupableRelatableTO) anyTO;
group = groupDAO.findByName(intAttrName.getMembershipOfGroup());
+ } else {
+ groupableTO = null;
+ group = null;
}
switch (intAttrName.getSchemaType()) {
@@ -798,29 +801,28 @@ public class MappingManagerImpl implements MappingManager {
if (groupableTO == null || group == null) {
anyTO.getPlainAttrs().add(attrTO);
} else {
- Optional<MembershipTO> membership = groupableTO.getMembership(group.getKey());
- if (!membership.isPresent()) {
- membership = Optional.of(
- new MembershipTO.Builder().group(group.getKey(), group.getName()).build());
- groupableTO.getMemberships().add(membership.get());
- }
- membership.get().getPlainAttrs().add(attrTO);
+ MembershipTO membership = groupableTO.getMembership(group.getKey()).orElseGet(() -> {
+ MembershipTO newMemb = new MembershipTO.Builder().group(group.getKey()).build();
+ groupableTO.getMemberships().add(newMemb);
+ return newMemb;
+ });
+ membership.getPlainAttrs().add(attrTO);
}
break;
case DERIVED:
attrTO = new AttrTO();
attrTO.setSchema(intAttrName.getSchemaName());
+
if (groupableTO == null || group == null) {
anyTO.getDerAttrs().add(attrTO);
} else {
- Optional<MembershipTO> membership = groupableTO.getMembership(group.getKey());
- if (!membership.isPresent()) {
- membership = Optional.of(
- new MembershipTO.Builder().group(group.getKey(), group.getName()).build());
- groupableTO.getMemberships().add(membership.get());
- }
- membership.get().getDerAttrs().add(attrTO);
+ MembershipTO membership = groupableTO.getMembership(group.getKey()).orElseGet(() -> {
+ MembershipTO newMemb = new MembershipTO.Builder().group(group.getKey()).build();
+ groupableTO.getMemberships().add(newMemb);
+ return newMemb;
+ });
+ membership.getDerAttrs().add(attrTO);
}
break;
@@ -838,13 +840,12 @@ public class MappingManagerImpl implements MappingManager {
if (groupableTO == null || group == null) {
anyTO.getVirAttrs().add(attrTO);
} else {
- Optional<MembershipTO> membership = groupableTO.getMembership(group.getKey());
- if (!membership.isPresent()) {
- membership = Optional.of(
- new MembershipTO.Builder().group(group.getKey(), group.getName()).build());
- groupableTO.getMemberships().add(membership.get());
- }
- membership.get().getVirAttrs().add(attrTO);
+ MembershipTO membership = groupableTO.getMembership(group.getKey()).orElseGet(() -> {
+ MembershipTO newMemb = new MembershipTO.Builder().group(group.getKey()).build();
+ groupableTO.getMemberships().add(newMemb);
+ return newMemb;
+ });
+ membership.getVirAttrs().add(attrTO);
}
break;
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
index 5c134df..c7499a8 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
@@ -69,6 +69,7 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
@@ -571,9 +572,9 @@ abstract class AbstractAnyDataBinder {
anyTO.getResources().addAll(resources.stream().map(Entity::getKey).collect(Collectors.toSet()));
}
- protected RelationshipTO getRelationshipTO(final String relationshipType, final Any<?> otherEnd) {
+ protected RelationshipTO getRelationshipTO(final String relationshipType, final AnyObject otherEnd) {
return new RelationshipTO.Builder().
- type(relationshipType).otherEnd(otherEnd.getType().getKey(), otherEnd.getKey()).
+ type(relationshipType).otherEnd(otherEnd.getType().getKey(), otherEnd.getKey(), otherEnd.getName()).
build();
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
index 129d0e4..1dd6194 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
@@ -101,11 +101,12 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
// relationships
anyObjectTO.getRelationships().addAll(
- anyObjectDAO.findAllRelationships(anyObject).stream().map(relationship -> getRelationshipTO(
- relationship.getType().getKey(),
- relationship.getLeftEnd().getKey().equals(anyObject.getKey())
- ? relationship.getRightEnd()
- : relationship.getLeftEnd())).
+ anyObjectDAO.findAllRelationships(anyObject).stream().
+ map(relationship -> getRelationshipTO(
+ relationship.getType().getKey(),
+ relationship.getLeftEnd().getKey().equals(anyObject.getKey())
+ ? relationship.getRightEnd()
+ : anyObject)).
collect(Collectors.toList()));
// memberships
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
index d328c43..58c2d7d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
@@ -602,10 +602,9 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
flatMap(role -> role.getPrivileges().stream()).map(Entity::getKey).collect(Collectors.toSet()));
// relationships
- userTO.getRelationships().addAll(
- user.getRelationships().stream().map(relationship -> getRelationshipTO(
- relationship.getType().getKey(), relationship.getRightEnd())).
- collect(Collectors.toList()));
+ userTO.getRelationships().addAll(user.getRelationships().stream().
+ map(relationship -> getRelationshipTO(relationship.getType().getKey(), relationship.getRightEnd())).
+ collect(Collectors.toList()));
// memberships
userTO.getMemberships().addAll(
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/pom.xml
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/pom.xml b/ext/flowable/client-console/pom.xml
index ef2e989..f076186 100644
--- a/ext/flowable/client-console/pom.xml
+++ b/ext/flowable/client-console/pom.xml
@@ -83,35 +83,37 @@ under the License.
<target>
<unzip src="${settings.localRepository}/org/flowable/flowable-ui-modeler-app/${flowable.version}/flowable-ui-modeler-app-${flowable.version}.war" dest="${flowable-modeler.directory}">
<patternset>
- <include name="WEB-INF/classes/static/**" />
- <include name="WEB-INF/lib/flowable-ui-modeler-logic-${flowable.version}.jar" />
+ <include name="WEB-INF/classes/static/**"/>
+ <include name="WEB-INF/lib/flowable-ui-modeler-logic-${flowable.version}.jar"/>
</patternset>
</unzip>
<unzip src="${flowable-modeler.directory}/WEB-INF/lib/flowable-ui-modeler-logic-${flowable.version}.jar" dest="${flowable-modeler.directory}">
<patternset>
- <include name="stencilset_bpmn.json" />
+ <include name="stencilset_bpmn.json"/>
</patternset>
</unzip>
<move todir="${flowable-modeler.directory}">
<fileset dir="${flowable-modeler.directory}/WEB-INF/classes/static/">
- <include name="**" />
+ <include name="**"/>
</fileset>
</move>
- <delete dir="${flowable-modeler.directory}/WEB-INF" />
+ <delete dir="${flowable-modeler.directory}/WEB-INF"/>
- <replace file="${flowable-modeler.directory}/index.html" token="</head>" value="<script type="text/javascript">window.onunload = refreshParent; function refreshParent() { window.opener.location.reload(); }</script></head>" />
- <replace file="${flowable-modeler.directory}/index.html" token=" ng-click="backToLanding()"" value=" disabled="disabled"" />
- <replace file="${flowable-modeler.directory}/index.html" token="<ul class="nav navbar-nav" id="main-nav"" value="<ul class="nav navbar-nav" id="main-nav" style="display: none;"" />
- <replace file="${flowable-modeler.directory}/index.html" token="<div class="pull-right" value="<div style="display: none;" class="pull-right" />
- <replace file="${flowable-modeler.directory}/editor-app/editor.html" token="<div class="btn-group pull-right"" value="<div style="display: none;" class="btn-group pull-right"" />
- <replace file="${flowable-modeler.directory}/editor-app/configuration/toolbar-default-actions.js" token="$location.path('/processes');" value="window.close();" />
+ <replace file="${flowable-modeler.directory}/index.html" token="</head>" value="<script type="text/javascript">window.onunload = refreshParent; function refreshParent() { window.opener.location.reload(); }</script></head>"/>
+ <replace file="${flowable-modeler.directory}/index.html" token=" ng-click="backToLanding()"" value=" disabled="disabled""/>
+ <replace file="${flowable-modeler.directory}/index.html" token="<ul class="nav navbar-nav" id="main-nav"" value="<ul class="nav navbar-nav" id="main-nav" style="display: none;""/>
+ <replace file="${flowable-modeler.directory}/index.html" token="<div class="pull-right" value="<div style="display: none;" class="pull-right"/>
+ <replace file="${flowable-modeler.directory}/editor-app/editor.html" token="<div class="btn-group pull-right"" value="<div style="display: none;" class="btn-group pull-right""/>
+ <replace file="${flowable-modeler.directory}/editor-app/configuration/toolbar-default-actions.js" token="$location.path('/processes');" value="window.close();"/>
- <copy file="${basedir}/src/main/resources/app-cfg.js" todir="${flowable-modeler.directory}/scripts" overwrite="true" />
- <copy file="${basedir}/src/main/resources/url-config.js" todir="${flowable-modeler.directory}/editor-app/configuration" overwrite="true" />
- <copy file="${basedir}/src/main/resources/toolbar.js" todir="${flowable-modeler.directory}/editor-app/configuration" overwrite="true" />
- <copy file="${basedir}/src/main/resources/save-model.html" todir="${flowable-modeler.directory}/editor-app/popups" overwrite="true" />
+ <copy file="${basedir}/src/main/resources/app-cfg.js" todir="${flowable-modeler.directory}/scripts" overwrite="true"/>
+ <copy file="${basedir}/src/main/resources/url-config.js" todir="${flowable-modeler.directory}/editor-app/configuration" overwrite="true"/>
+ <copy file="${basedir}/src/main/resources/toolbar.js" todir="${flowable-modeler.directory}/editor-app/configuration" overwrite="true"/>
+ <copy file="${basedir}/src/main/resources/save-model.html" todir="${flowable-modeler.directory}/editor-app/popups" overwrite="true"/>
+
+ <patch patchfile="${basedir}/src/main/resources/dropdown.diff" dir="${flowable-modeler.directory}" strip="1"/>
</target>
</configuration>
<goals>
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/Approval.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/Approval.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/Approval.java
index 3bea1a9..6a66afc 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/Approval.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/Approval.java
@@ -45,7 +45,6 @@ import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
-import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -103,7 +102,7 @@ public abstract class Approval extends Panel {
break;
case Date:
- final FastDateFormat formatter = FastDateFormat.getInstance(prop.getDatePattern());
+ FastDateFormat formatter = FastDateFormat.getInstance(prop.getDatePattern());
field = new AjaxDateTimeFieldPanel("value", label, new PropertyModel<Date>(prop, "value") {
private static final long serialVersionUID = -3743432456095828573L;
@@ -111,11 +110,9 @@ public abstract class Approval extends Panel {
@Override
public Date getObject() {
try {
- if (StringUtils.isBlank(prop.getValue())) {
- return null;
- } else {
- return formatter.parse(prop.getValue());
- }
+ return StringUtils.isBlank(prop.getValue())
+ ? null
+ : formatter.parse(prop.getValue());
} catch (ParseException e) {
LOG.error("Unparsable date: {}", prop.getValue(), e);
return null;
@@ -131,19 +128,17 @@ public abstract class Approval extends Panel {
break;
case Enum:
- MapChoiceRenderer<String, String> enumCR = new MapChoiceRenderer<>(prop.getEnumValues());
-
field = new AjaxDropDownChoicePanel(
"value", label, new PropertyModel<String>(prop, "value"), false).
- setChoiceRenderer(enumCR).setChoices(new Model<ArrayList<String>>() {
-
- private static final long serialVersionUID = -858521070366432018L;
+ setChoiceRenderer(new MapChoiceRenderer(prop.getEnumValues())).
+ setChoices(new ArrayList<>(prop.getEnumValues().keySet()));
+ break;
- @Override
- public ArrayList<String> getObject() {
- return new ArrayList<>(prop.getEnumValues().keySet());
- }
- });
+ case Dropdown:
+ field = new AjaxDropDownChoicePanel(
+ "value", label, new PropertyModel<String>(prop, "value"), false).
+ setChoiceRenderer(new MapChoiceRenderer(prop.getDropdownValues())).
+ setChoices(new ArrayList<>(prop.getDropdownValues().keySet()));
break;
case Long:
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
index e16f5c2..577ea65 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
@@ -113,7 +113,7 @@ public class ApprovalDirectoryPanel
initResultTable();
- MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, FlowableEntitlement.WORKFLOW_FORM_SUBMIT);
+ MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, FlowableEntitlement.USER_REQUEST_FORM_SUBMIT);
}
@Override
@@ -121,7 +121,7 @@ public class ApprovalDirectoryPanel
List<IColumn<UserRequestForm, String>> columns = new ArrayList<>();
columns.add(new PropertyColumn<>(
- new ResourceModel("taskId"), "taskId", "taskId"));
+ new ResourceModel("bpmnProcess"), "bpmnProcess", "bpmnProcess"));
columns.add(new PropertyColumn<>(
new ResourceModel("key"), "formKey", "formKey"));
columns.add(new PropertyColumn<>(
@@ -151,7 +151,7 @@ public class ApprovalDirectoryPanel
((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
target.add(container);
}
- }, ActionLink.ActionType.CLAIM, FlowableEntitlement.WORKFLOW_FORM_CLAIM);
+ }, ActionLink.ActionType.CLAIM, FlowableEntitlement.USER_REQUEST_FORM_CLAIM);
panel.add(new ActionLink<UserRequestForm>() {
@@ -190,7 +190,7 @@ public class ApprovalDirectoryPanel
equals(model.getObject().getOwner());
}
- }, ActionLink.ActionType.MANAGE_APPROVAL, FlowableEntitlement.WORKFLOW_FORM_READ);
+ }, ActionLink.ActionType.MANAGE_APPROVAL, FlowableEntitlement.USER_REQUEST_FORM_SUBMIT);
// SYNCOPE-1200 edit user while in approval state
panel.add(new ActionLink<UserRequestForm>() {
@@ -239,7 +239,7 @@ public class ApprovalDirectoryPanel
equals(model.getObject().getOwner());
}
- }, ActionLink.ActionType.EDIT_APPROVAL, FlowableEntitlement.WORKFLOW_FORM_SUBMIT);
+ }, ActionLink.ActionType.EDIT_APPROVAL, FlowableEntitlement.USER_REQUEST_FORM_SUBMIT);
return panel;
}
@@ -326,8 +326,6 @@ public class ApprovalDirectoryPanel
protected Serializable onApplyInternal(final AnyWrapper<UserTO> modelObject) {
UserTO inner = modelObject.getInnerObject();
- ProvisioningResult<UserTO> result;
-
UserPatch patch = AnyOperations.diff(inner, formTO.getUserTO(), false);
if (StringUtils.isNotBlank(inner.getPassword())) {
@@ -337,16 +335,15 @@ public class ApprovalDirectoryPanel
build();
patch.setPassword(passwordPatch);
}
+
// update just if it is changed
+ ProvisioningResult<UserTO> result;
if (patch.isEmpty()) {
result = new ProvisioningResult<>();
result.setEntity(inner);
} else {
result = userRestClient.update(getOriginalItem().getInnerObject().getETagValue(), patch);
- UserRequestForm workFlowTO = restClient.getForms(result.getEntity().getKey()).get(0);
- if (workFlowTO != null) {
- claimForm(workFlowTO.getTaskId());
- }
+ restClient.getForm(result.getEntity().getKey()).ifPresent(form -> claimForm(form.getTaskId()));
}
return result;
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/pages/Flowable.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/pages/Flowable.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/pages/Flowable.java
index 562aad1..8062a77 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/pages/Flowable.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/pages/Flowable.java
@@ -23,7 +23,7 @@ import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.client.console.annotations.ExtPage;
import org.apache.syncope.client.console.panels.BpmnProcessDirectoryPanel;
import org.apache.syncope.client.console.wizards.WizardMgtPanel;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.common.lib.types.FlowableEntitlement;
import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
import org.apache.wicket.markup.html.WebMarkupContainer;
@@ -48,7 +48,7 @@ public class Flowable extends BaseExtPage {
disabled.setOutputMarkupPlaceholderTag(true);
content.add(disabled);
- WizardMgtPanel<BpmnProcessTO> bpmnProcessesPanel = new BpmnProcessDirectoryPanel.Builder(getPageReference()) {
+ WizardMgtPanel<BpmnProcess> bpmnProcessesPanel = new BpmnProcessDirectoryPanel.Builder(getPageReference()) {
private static final long serialVersionUID = -5960765294082359003L;
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java
index b7914bb..8f4d566 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java
@@ -43,7 +43,7 @@ import org.apache.syncope.client.console.wicket.markup.html.form.XMLEditorPanel;
import org.apache.syncope.client.console.wizards.AjaxWizardBuilder;
import org.apache.syncope.client.console.wizards.WizardMgtPanel;
import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.common.lib.types.FlowableEntitlement;
import org.apache.wicket.Page;
import org.apache.wicket.PageReference;
@@ -65,7 +65,7 @@ import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.util.io.IOUtils;
public class BpmnProcessDirectoryPanel extends DirectoryPanel<
- BpmnProcessTO, BpmnProcessTO, BpmProcessDataProvider, BpmnProcessRestClient> {
+ BpmnProcess, BpmnProcess, BpmProcessDataProvider, BpmnProcessRestClient> {
private static final long serialVersionUID = 2705668831139984998L;
@@ -76,13 +76,13 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
protected BpmnProcessDirectoryPanel(final String id, final Builder builder) {
super(id, builder);
- this.addNewItemPanelBuilder(new AjaxWizardBuilder<BpmnProcessTO>(new BpmnProcessTO(), pageRef) {
+ this.addNewItemPanelBuilder(new AjaxWizardBuilder<BpmnProcess>(new BpmnProcess(), pageRef) {
private static final long serialVersionUID = 1633859795677053912L;
@Override
protected WizardModel buildModelSteps(
- final BpmnProcessTO modelObject, final WizardModel wizardModel) {
+ final BpmnProcess modelObject, final WizardModel wizardModel) {
return wizardModel;
}
@@ -133,8 +133,8 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
@Override
- protected List<IColumn<BpmnProcessTO, String>> getColumns() {
- List<IColumn<BpmnProcessTO, String>> columns = new ArrayList<>();
+ protected List<IColumn<BpmnProcess, String>> getColumns() {
+ List<IColumn<BpmnProcess, String>> columns = new ArrayList<>();
columns.add(new PropertyColumn<>(new ResourceModel("key"), "key"));
columns.add(new PropertyColumn<>(new ResourceModel("name"), "name", "name"));
@@ -143,15 +143,15 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
@Override
- public ActionsPanel<BpmnProcessTO> getActions(final IModel<BpmnProcessTO> model) {
- final ActionsPanel<BpmnProcessTO> panel = super.getActions(model);
+ public ActionsPanel<BpmnProcess> getActions(final IModel<BpmnProcess> model) {
+ final ActionsPanel<BpmnProcess> panel = super.getActions(model);
- panel.add(new ActionLink<BpmnProcessTO>() {
+ panel.add(new ActionLink<BpmnProcess>() {
private static final long serialVersionUID = -184018732772021627L;
@Override
- public void onClick(final AjaxRequestTarget target, final BpmnProcessTO ignore) {
+ public void onClick(final AjaxRequestTarget target, final BpmnProcess ignore) {
final IModel<String> wfDefinition = new Model<>();
try {
wfDefinition.setObject(IOUtils.toString(restClient.getDefinition(
@@ -189,12 +189,12 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
}, ActionLink.ActionType.EDIT, FlowableEntitlement.BPMN_PROCESS_SET);
- panel.add(new ActionLink<BpmnProcessTO>() {
+ panel.add(new ActionLink<BpmnProcess>() {
private static final long serialVersionUID = 3109256773218160485L;
@Override
- public void onClick(final AjaxRequestTarget target, final BpmnProcessTO ignore) {
+ public void onClick(final AjaxRequestTarget target, final BpmnProcess ignore) {
modal.header(Model.of(model.getObject().getKey()));
modal.setContent(new ImageModalPanel<>(
modal, restClient.getDiagram(model.getObject().getKey()), pageRef));
@@ -203,7 +203,7 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
}, ActionLink.ActionType.VIEW, FlowableEntitlement.BPMN_PROCESS_GET);
- panel.add(new ActionLink<BpmnProcessTO>() {
+ panel.add(new ActionLink<BpmnProcess>() {
private static final long serialVersionUID = -184018732772021627L;
@@ -222,22 +222,22 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
@Override
- public void onClick(final AjaxRequestTarget target, final BpmnProcessTO ignore) {
+ public void onClick(final AjaxRequestTarget target, final BpmnProcess ignore) {
// do nothing
}
}, ActionLink.ActionType.EXTERNAL_EDITOR, FlowableEntitlement.BPMN_PROCESS_SET);
- panel.add(new ActionLink<BpmnProcessTO>() {
+ panel.add(new ActionLink<BpmnProcess>() {
private static final long serialVersionUID = -7978723352517770644L;
@Override
- protected boolean statusCondition(final BpmnProcessTO modelObject) {
+ protected boolean statusCondition(final BpmnProcess modelObject) {
return !modelObject.isUserWorkflow();
}
@Override
- public void onClick(final AjaxRequestTarget target, final BpmnProcessTO ignore) {
+ public void onClick(final AjaxRequestTarget target, final BpmnProcess ignore) {
try {
restClient.deleteDefinition(model.getObject().getKey());
SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
@@ -260,7 +260,7 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
public abstract static class Builder
- extends DirectoryPanel.Builder<BpmnProcessTO, BpmnProcessTO, BpmnProcessRestClient> {
+ extends DirectoryPanel.Builder<BpmnProcess, BpmnProcess, BpmnProcessRestClient> {
private static final long serialVersionUID = 5088962796986706805L;
@@ -269,16 +269,16 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
@Override
- protected WizardMgtPanel<BpmnProcessTO> newInstance(final String id, final boolean wizardInModal) {
+ protected WizardMgtPanel<BpmnProcess> newInstance(final String id, final boolean wizardInModal) {
return new BpmnProcessDirectoryPanel(id, this);
}
}
- protected class BpmProcessDataProvider extends DirectoryDataProvider<BpmnProcessTO> {
+ protected class BpmProcessDataProvider extends DirectoryDataProvider<BpmnProcess> {
private static final long serialVersionUID = 1764153405387687592L;
- private final SortableDataProviderComparator<BpmnProcessTO> comparator;
+ private final SortableDataProviderComparator<BpmnProcess> comparator;
private final BpmnProcessRestClient restClient = new BpmnProcessRestClient();
@@ -289,8 +289,8 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
@Override
- public Iterator<BpmnProcessTO> iterator(final long first, final long count) {
- List<BpmnProcessTO> result = restClient.getDefinitions();
+ public Iterator<BpmnProcess> iterator(final long first, final long count) {
+ List<BpmnProcess> result = restClient.getDefinitions();
Collections.sort(result, comparator);
return result.subList((int) first, (int) first + (int) count).iterator();
}
@@ -301,7 +301,7 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
@Override
- public IModel<BpmnProcessTO> model(final BpmnProcessTO object) {
+ public IModel<BpmnProcess> model(final BpmnProcess object) {
return new CompoundPropertyModel<>(object);
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/AbstractBpmnProcessResource.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/AbstractBpmnProcessResource.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/AbstractBpmnProcessResource.java
index 91a42e3..7ad5f24 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/AbstractBpmnProcessResource.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/AbstractBpmnProcessResource.java
@@ -21,7 +21,7 @@ package org.apache.syncope.client.console.resources;
import javax.ws.rs.NotFoundException;
import org.apache.syncope.client.console.commons.Constants;
import org.apache.syncope.client.console.rest.BpmnProcessRestClient;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.wicket.request.resource.AbstractResource;
import org.apache.wicket.util.string.StringValue;
import org.slf4j.Logger;
@@ -35,10 +35,10 @@ abstract class AbstractBpmnProcessResource extends AbstractResource {
protected final BpmnProcessRestClient restClient = new BpmnProcessRestClient();
- protected BpmnProcessTO getBpmnProcess(final Attributes attributes) {
+ protected BpmnProcess getBpmnProcess(final Attributes attributes) {
StringValue modelId = attributes.getRequest().getQueryParameters().getParameterValue(Constants.MODEL_ID_PARAM);
- BpmnProcessTO bpmnProcess = modelId == null || modelId.isNull()
+ BpmnProcess bpmnProcess = modelId == null || modelId.isNull()
? null
: restClient.getDefinitions().stream().
filter(object -> modelId.toString().equals(object.getModelId())).findAny().orElse(null);
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessGETResource.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessGETResource.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessGETResource.java
index ba34502..dfe633e 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessGETResource.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessGETResource.java
@@ -23,7 +23,7 @@ import java.nio.charset.StandardCharsets;
import javax.ws.rs.core.MediaType;
import org.apache.syncope.client.console.annotations.Resource;
import org.apache.syncope.client.console.rest.BpmnProcessRestClient;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.wicket.util.io.IOUtils;
/**
@@ -36,7 +36,7 @@ public class BpmnProcessGETResource extends AbstractBpmnProcessResource {
@Override
protected ResourceResponse newResourceResponse(final Attributes attributes) {
- final BpmnProcessTO toGet = getBpmnProcess(attributes);
+ final BpmnProcess toGet = getBpmnProcess(attributes);
ResourceResponse response = new ResourceResponse();
response.disableCaching();
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessPUTResource.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessPUTResource.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessPUTResource.java
index d583396..1031ce8 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessPUTResource.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessPUTResource.java
@@ -24,7 +24,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.cxf.common.util.UrlUtils;
import org.apache.syncope.client.console.annotations.Resource;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.wicket.util.io.IOUtils;
/**
@@ -52,7 +52,7 @@ public class BpmnProcessPUTResource extends AbstractBpmnProcessResource {
LOG.error("Could not extract BPMN process", e);
}
- BpmnProcessTO toSet = getBpmnProcess(attributes);
+ BpmnProcess toSet = getBpmnProcess(attributes);
if (definition == null || toSet == null) {
return new ResourceResponse().setStatusCode(Response.Status.BAD_REQUEST.getStatusCode()).
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/BpmnProcessRestClient.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/BpmnProcessRestClient.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/BpmnProcessRestClient.java
index 2b7c368..9e88431 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/BpmnProcessRestClient.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/BpmnProcessRestClient.java
@@ -25,7 +25,7 @@ import javax.ws.rs.core.Response;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.common.rest.api.RESTHeaders;
import org.apache.syncope.common.rest.api.service.BpmnProcessService;
@@ -37,7 +37,7 @@ public class BpmnProcessRestClient extends BaseRestClient {
return SyncopeConsoleSession.get().getService(mediaType, BpmnProcessService.class);
}
- public List<BpmnProcessTO> getDefinitions() {
+ public List<BpmnProcess> getDefinitions() {
return getService(BpmnProcessService.class).list();
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/UserRequestRestClient.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/UserRequestRestClient.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/UserRequestRestClient.java
index 555555b..e3a179f 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/UserRequestRestClient.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/UserRequestRestClient.java
@@ -19,6 +19,8 @@
package org.apache.syncope.client.console.rest;
import java.util.List;
+import java.util.Optional;
+import org.apache.syncope.common.lib.to.PagedResult;
import org.apache.syncope.common.lib.to.UserRequestForm;
import org.apache.syncope.common.rest.api.beans.UserRequestFormQuery;
import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
@@ -40,8 +42,13 @@ public class UserRequestRestClient extends BaseRestClient {
getResult();
}
- public List<UserRequestForm> getForms(final String userKey) {
- return getService(UserRequestService.class).getForms(userKey);
+ public Optional<UserRequestForm> getForm(final String userKey) {
+ PagedResult<UserRequestForm> forms = getService(UserRequestService.class).
+ getForms(new UserRequestFormQuery.Builder().user(userKey).page(1).size(1).build());
+ UserRequestForm form = forms.getResult().isEmpty()
+ ? null
+ : forms.getResult().get(0);
+ return Optional.ofNullable(form);
}
public UserRequestForm claimForm(final String taskKey) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/widgets/ApprovalsWidget.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/widgets/ApprovalsWidget.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/widgets/ApprovalsWidget.java
index 8f8329e..9a9fd2d 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/widgets/ApprovalsWidget.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/widgets/ApprovalsWidget.java
@@ -87,8 +87,7 @@ public class ApprovalsWidget extends ExtAlertWidget<UserRequestForm> {
@Override
protected int getLatestAlertsSize() {
- return SyncopeConsoleSession.get().owns(FlowableEntitlement.WORKFLOW_FORM_LIST)
- && SyncopeConsoleSession.get().owns(FlowableEntitlement.WORKFLOW_FORM_READ)
+ return SyncopeConsoleSession.get().owns(FlowableEntitlement.USER_REQUEST_FORM_LIST)
? restClient.countForms()
: 0;
}
@@ -102,9 +101,7 @@ public class ApprovalsWidget extends ExtAlertWidget<UserRequestForm> {
@Override
public List<UserRequestForm> getObject() {
List<UserRequestForm> updatedApprovals;
- if (SyncopeConsoleSession.get().owns(FlowableEntitlement.WORKFLOW_FORM_LIST)
- && SyncopeConsoleSession.get().owns(FlowableEntitlement.WORKFLOW_FORM_READ)) {
-
+ if (SyncopeConsoleSession.get().owns(FlowableEntitlement.USER_REQUEST_FORM_LIST)) {
updatedApprovals = restClient.getForms(1, MAX_SIZE, new SortParam<>("createTime", true));
} else {
updatedApprovals = Collections.<UserRequestForm>emptyList();
@@ -118,7 +115,8 @@ public class ApprovalsWidget extends ExtAlertWidget<UserRequestForm> {
@Override
protected AbstractLink getEventsLink(final String linkid) {
BookmarkablePageLink<Approvals> approvals = BookmarkablePageLinkBuilder.build(linkid, Approvals.class);
- MetaDataRoleAuthorizationStrategy.authorize(approvals, WebPage.ENABLE, FlowableEntitlement.WORKFLOW_FORM_LIST);
+ MetaDataRoleAuthorizationStrategy.authorize(
+ approvals, WebPage.ENABLE, FlowableEntitlement.USER_REQUEST_FORM_LIST);
return approvals;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/src/main/resources/dropdown.diff
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/resources/dropdown.diff b/ext/flowable/client-console/src/main/resources/dropdown.diff
new file mode 100644
index 0000000..80fe1e7
--- /dev/null
+++ b/ext/flowable/client-console/src/main/resources/dropdown.diff
@@ -0,0 +1,139 @@
+# 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.
+diff --git a/editor-app/configuration/properties-form-properties-controller.js b/editor-app/configuration/properties-form-properties-controller.js
+index ca8f051..fc02151 100644
+--- a/editor-app/configuration/properties-form-properties-controller.js
++++ b/editor-app/configuration/properties-form-properties-controller.js
+@@ -102,6 +102,20 @@ angular.module('flowableModeler').controller('FlowableFormPropertiesPopupCtrl',
+ { field: 'name', displayName: $scope.labels.nameLabel}]
+ }
+
++ $scope.dropdownGridOptions = {
++ data: $scope.enumValues,
++ headerRowHeight: 28,
++ enableRowSelection: true,
++ enableRowHeaderSelection: false,
++ multiSelect: false,
++ modifierKeysToMultiSelect: false,
++ enableHorizontalScrollbar: 0,
++ enableColumnMenus: false,
++ enableSorting: false,
++ columnDefs: [{ field: 'id', displayName: $scope.labels.idLabel },
++ { field: 'name', displayName: $scope.labels.nameLabel}]
++ }
++
+ $scope.gridOptions.onRegisterApi = function (gridApi) {
+ //set gridApi on scope
+ $scope.gridApi = gridApi;
+@@ -124,6 +138,13 @@ angular.module('flowableModeler').controller('FlowableFormPropertiesPopupCtrl',
+ $scope.selectedEnumValue = row.entity;
+ });
+ };
++ $scope.dropdownGridOptions.onRegisterApi = function (gridApi) {
++ //set gridApi on scope
++ $scope.dropdownGridApi = gridApi;
++ gridApi.selection.on.rowSelectionChanged($scope, function (row) {
++ $scope.selectedDropdownValue = row.entity;
++ });
++ };
+ });
+
+ // Handler for when the value of the type dropdown changes
+@@ -143,7 +164,12 @@ angular.module('flowableModeler').controller('FlowableFormPropertiesPopupCtrl',
+ for (var i = 0; i < $scope.selectedProperty.enumValues.length; i++) {
+ $scope.enumValues.push($scope.selectedProperty.enumValues[i]);
+ }
+-
++ } else if ($scope.selectedProperty.type === 'dropdown') {
++ $scope.selectedProperty.enumValues = [ {id: 'dropdownValueProvider', name: 'provider'}];
++ $scope.enumValues.length = 0;
++ for (var i = 0; i < $scope.selectedProperty.enumValues.length; i++) {
++ $scope.enumValues.push($scope.selectedProperty.enumValues[i]);
++ }
+ } else {
+ delete $scope.selectedProperty.enumValues;
+ $scope.enumValues.length = 0;
+@@ -324,4 +350,4 @@ angular.module('flowableModeler').controller('FlowableFormPropertiesPopupCtrl',
+ };
+
+ }])
+-;
+\ No newline at end of file
++;
+diff --git a/editor-app/configuration/properties/form-properties-popup.html b/editor-app/configuration/properties/form-properties-popup.html
+index 17c5ca8..57a24e5 100644
+--- a/editor-app/configuration/properties/form-properties-popup.html
++++ b/editor-app/configuration/properties/form-properties-popup.html
+@@ -42,6 +42,7 @@
+ <option>boolean</option>
+ <option>date</option>
+ <option>enum</option>
++ <option>dropdown</option>
+ </select>
+ </div>
+ <div class="form-group" ng-show="selectedProperty.datePattern">
+@@ -80,6 +81,38 @@
+ </div>
+ </div>
+ </div>
++ <div ng-show="selectedProperty.type == 'dropdown'" style="padding-bottom:10px">
++ <div class="row row-no-gutter">
++ <div class="col-xs-6">
++ <div ng-if="translationsRetrieved" class="kis-listener-grid" ui-grid="dropdownGridOptions" ui-grid-selection ui-grid-auto-resize></div>
++ <!--<div class="pull-right">
++ <div class="btn-group">
++ <a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.MOVE.UP | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="moveEnumValueUp()"><i class="glyphicon glyphicon-arrow-up"></i></a>
++ <a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.MOVE.DOWN | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="moveEnumValueDown()"><i class="glyphicon glyphicon-arrow-down"></i></a>
++ </div>
++ <div class="btn-group">
++ <a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.ADD | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="addNewEnumValue()"><i class="glyphicon glyphicon-plus"></i></a>
++ <a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.REMOVE | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="removeEnumValue()"><i class="glyphicon glyphicon-minus"></i></a>
++ </div>
++ </div>-->
++ </div>
++
++ <div class="col-xs-6">
++ <div ng-show="selectedDropdownValue">
++
++ <div class="form-group">
++ <label for="classField">{{'PROPERTY.FORMPROPERTIES.VALUES.ID' | translate}}</label>
++ <input type="text" id="classField" class="form-control" ng-model="selectedDropdownValue.id" placeholder="{{'PROPERTY.FORMPROPERTIES.VALUES.ID.PLACEHOLDER' | translate}}" />
++ </div>
++ <div class="form-group">
++ <label for="classField">{{'PROPERTY.FORMPROPERTIES.VALUES.NAME' | translate}}</label>
++ <input type="text" id="classField" class="form-control" ng-model="selectedDropdownValue.name" placeholder="{{'PROPERTY.FORMPROPERTIES.VALUES.NAME.PLACEHOLDER' | translate}}" />
++ </div>
++ </div>
++ <div ng-show="!selectedDropdownValue" class="muted no-property-selected" translate>PROPERTY.FORMPROPERTIES.DROPDOWNVALUES.EMPTY</div>
++ </div>
++ </div>
++ </div>
+ <div class="form-group">
+ <label for="expressionField">{{'PROPERTY.FORMPROPERTIES.EXPRESSION' | translate}}</label>
+ <input id="expressionField" class="form-control" type="text" ng-model="selectedProperty.expression" placeholder="{{'PROPERTY.FORMPROPERTIES.EXPRESSION.PLACEHOLDER' | translate }}" />
+diff --git a/i18n/en.json b/i18n/en.json
+index 7d0e40a..1067dad 100644
+--- a/i18n/en.json
++++ b/i18n/en.json
+@@ -824,6 +824,7 @@
+ "PROPERTY.FORMPROPERTIES.DATEPATTERN.PLACEHOLDER" : "Enter date pattern",
+ "PROPERTY.FORMPROPERTIES.VALUES" : "Values",
+ "PROPERTY.FORMPROPERTIES.ENUMVALUES.EMPTY" : "No enum value selected",
++ "PROPERTY.FORMPROPERTIES.DROPDOWNVALUES.EMPTY" : "No dropdown value selected",
+ "PROPERTY.FORMPROPERTIES.VALUES.ID" : "Id",
+ "PROPERTY.FORMPROPERTIES.VALUES.NAME" : "Name",
+ "PROPERTY.FORMPROPERTIES.VALUES.ID.PLACEHOLDER" : "Enter id of a value",
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals.properties
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals.properties b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals.properties
index 1ea8063..84b9c85 100644
--- a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals.properties
+++ b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals.properties
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-taskId=Task
+bpmnProcess=User Request
key=Key
description=Description
createTime=Create Time
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_it.properties
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_it.properties b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_it.properties
index 7e12ce5..f25abd8 100644
--- a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_it.properties
+++ b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_it.properties
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-taskId=Task
+bpmnProcess=User Request
key=Chiave
description=Descrizione
createTime=Data di creazione
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ja.properties
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ja.properties b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ja.properties
index b2ff626..dcca6e1 100644
--- a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ja.properties
+++ b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ja.properties
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-taskId=\u30bf\u30b9\u30af
+bpmnProcess=User Request
key=\u30ad\u30fc
description=\u8aac\u660e
createTime=\u4f5c\u6210\u6642\u523b
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_pt_BR.properties
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_pt_BR.properties b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_pt_BR.properties
index e5ff74c..88a9e05 100644
--- a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_pt_BR.properties
+++ b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_pt_BR.properties
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-taskId=Tarefa
+bpmnProcess=User Request
key=Chave
description=Descri\u00e7\u00e3o
createTime=Tempo de Cria\u00e7\u00e3o
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ru.properties
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ru.properties b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ru.properties
index 6f4fb58..2e7a199 100644
--- a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ru.properties
+++ b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ru.properties
@@ -16,7 +16,7 @@
# under the License.
#
# taskId=\u00d0\u0097\u00d0\u00b0\u00d1\u008f\u00d0\u00b2\u00d0\u00ba\u00d0\u00b0
-taskId=\u0417\u0430\u044f\u0432\u043a\u0430
+bpmnProcess=User Request
# key=\u00d0\u0098\u00d0\u00b4\u00d0\u00b5\u00d0\u00bd\u00d1\u0082\u00d0\u00b8\u00d1\u0084\u00d0\u00b8\u00d0\u00ba\u00d0\u00b0\u00d1\u0082\u00d0\u00be\u00d1\u0080
key=\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440
# description=\u00d0\u009e\u00d0\u00bf\u00d0\u00b8\u00d1\u0081\u00d0\u00b0\u00d0\u00bd\u00d0\u00b8\u00d0\u00b5
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcess.java
----------------------------------------------------------------------
diff --git a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcess.java b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcess.java
new file mode 100644
index 0000000..35a7883
--- /dev/null
+++ b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcess.java
@@ -0,0 +1,72 @@
+/*
+ * 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 javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+@XmlRootElement(name = "bpmnProcess")
+@XmlType
+public class BpmnProcess extends AbstractBaseBean implements EntityTO {
+
+ private static final long serialVersionUID = -7044543391316529128L;
+
+ private String key;
+
+ private String modelId;
+
+ private String name;
+
+ private boolean userWorkflow;
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+
+ @Override
+ public void setKey(final String key) {
+ this.key = key;
+ }
+
+ public String getModelId() {
+ return modelId;
+ }
+
+ public void setModelId(final String modelId) {
+ this.modelId = modelId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public boolean isUserWorkflow() {
+ return userWorkflow;
+ }
+
+ public void setUserWorkflow(final boolean userWorkflow) {
+ this.userWorkflow = userWorkflow;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcessTO.java
----------------------------------------------------------------------
diff --git a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcessTO.java b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcessTO.java
deleted file mode 100644
index bb67e3e..0000000
--- a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcessTO.java
+++ /dev/null
@@ -1,72 +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.to;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-
-@XmlRootElement(name = "bpmnProcess")
-@XmlType
-public class BpmnProcessTO extends AbstractBaseBean implements EntityTO {
-
- private static final long serialVersionUID = -7044543391316529128L;
-
- private String key;
-
- private String modelId;
-
- private String name;
-
- private boolean userWorkflow;
-
- @Override
- public String getKey() {
- return key;
- }
-
- @Override
- public void setKey(final String key) {
- this.key = key;
- }
-
- public String getModelId() {
- return modelId;
- }
-
- public void setModelId(final String modelId) {
- this.modelId = modelId;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(final String name) {
- this.name = name;
- }
-
- public boolean isUserWorkflow() {
- return userWorkflow;
- }
-
- public void setUserWorkflow(final boolean userWorkflow) {
- this.userWorkflow = userWorkflow;
- }
-}
[2/6] syncope git commit: [SYNCOPE-1369] User requests forms now
support dropdowns - via Flowable customization
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequest.java
----------------------------------------------------------------------
diff --git a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequest.java b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequest.java
new file mode 100644
index 0000000..251eb89
--- /dev/null
+++ b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequest.java
@@ -0,0 +1,70 @@
+/*
+ * 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 javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+@XmlRootElement(name = "userRequest")
+@XmlType
+public class UserRequest extends AbstractBaseBean {
+
+ private static final long serialVersionUID = -8430826310789942133L;
+
+ private String bpmnProcess;
+
+ private String user;
+
+ private String executionId;
+
+ private String activityId;
+
+ public String getBpmnProcess() {
+ return bpmnProcess;
+ }
+
+ public void setBpmnProcess(final String bpmnProcess) {
+ this.bpmnProcess = bpmnProcess;
+ }
+
+ public String getUser() {
+ return user;
+ }
+
+ public void setUser(final String user) {
+ this.user = user;
+ }
+
+ public String getExecutionId() {
+ return executionId;
+ }
+
+ public void setExecutionId(final String executionId) {
+ this.executionId = executionId;
+ }
+
+ public String getActivityId() {
+ return activityId;
+ }
+
+ public void setActivityId(final String activityId) {
+ this.activityId = activityId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestForm.java
----------------------------------------------------------------------
diff --git a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestForm.java b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestForm.java
index 897cfc0..22118b5 100644
--- a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestForm.java
+++ b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestForm.java
@@ -37,8 +37,12 @@ public class UserRequestForm extends AbstractBaseBean {
private static final long serialVersionUID = -7044543391316529128L;
+ private String bpmnProcess;
+
private String username;
+ private String executionId;
+
private String taskId;
private String formKey;
@@ -55,6 +59,14 @@ public class UserRequestForm extends AbstractBaseBean {
private final List<UserRequestFormProperty> properties = new ArrayList<>();
+ public String getBpmnProcess() {
+ return bpmnProcess;
+ }
+
+ public void setBpmnProcess(final String bpmnProcess) {
+ this.bpmnProcess = bpmnProcess;
+ }
+
public String getUsername() {
return username;
}
@@ -63,6 +75,14 @@ public class UserRequestForm extends AbstractBaseBean {
this.username = username;
}
+ public String getExecutionId() {
+ return executionId;
+ }
+
+ public void setExecutionId(final String executionId) {
+ this.executionId = executionId;
+ }
+
public String getTaskId() {
return taskId;
}
@@ -138,9 +158,9 @@ public class UserRequestForm extends AbstractBaseBean {
return properties.stream().filter(property -> id.equals(property.getId())).findFirst();
}
- @XmlElementWrapper(name = "workflowFormProperties")
- @XmlElement(name = "workflowFormProperty")
- @JsonProperty("workflowFormProperties")
+ @XmlElementWrapper(name = "properties")
+ @XmlElement(name = "property")
+ @JsonProperty("properties")
public List<UserRequestFormProperty> getProperties() {
return properties;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestFormProperty.java
----------------------------------------------------------------------
diff --git a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestFormProperty.java b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestFormProperty.java
index 0a431c6..95f2fec 100644
--- a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestFormProperty.java
+++ b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestFormProperty.java
@@ -51,6 +51,9 @@ public class UserRequestFormProperty extends AbstractBaseBean {
@XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
private final Map<String, String> enumValues = new HashMap<>();
+ @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
+ private final Map<String, String> dropdownValues = new HashMap<>();
+
private String value;
public String getId() {
@@ -114,6 +117,11 @@ public class UserRequestFormProperty extends AbstractBaseBean {
return enumValues;
}
+ @JsonProperty
+ public Map<String, String> getDropdownValues() {
+ return dropdownValues;
+ }
+
public String getValue() {
return value;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestTO.java
----------------------------------------------------------------------
diff --git a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestTO.java b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestTO.java
deleted file mode 100644
index d5fad6c..0000000
--- a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestTO.java
+++ /dev/null
@@ -1,70 +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.to;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-
-@XmlRootElement(name = "userRequest")
-@XmlType
-public class UserRequestTO extends AbstractBaseBean {
-
- private static final long serialVersionUID = -8430826310789942133L;
-
- private String processInstanceId;
-
- private String executionId;
-
- private String bpmnProcess;
-
- private String user;
-
- public String getProcessInstanceId() {
- return processInstanceId;
- }
-
- public void setProcessInstanceId(final String processInstanceId) {
- this.processInstanceId = processInstanceId;
- }
-
- public String getExecutionId() {
- return executionId;
- }
-
- public void setExecutionId(final String executionId) {
- this.executionId = executionId;
- }
-
- public String getBpmnProcess() {
- return bpmnProcess;
- }
-
- public void setBpmnProcess(final String bpmnProcess) {
- this.bpmnProcess = bpmnProcess;
- }
-
- public String getUser() {
- return user;
- }
-
- public void setUser(final String user) {
- this.user = user;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/FlowableEntitlement.java
----------------------------------------------------------------------
diff --git a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/FlowableEntitlement.java b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/FlowableEntitlement.java
index 43825a4..fbf5b02 100644
--- a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/FlowableEntitlement.java
+++ b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/FlowableEntitlement.java
@@ -36,19 +36,13 @@ public final class FlowableEntitlement {
public static final String WORKFLOW_TASK_LIST = "WORKFLOW_TASK_LIST";
- public static final String WORKFLOW_FORM_LIST = "WORKFLOW_FORM_LIST";
+ public static final String USER_REQUEST_LIST = "USER_REQUEST_LIST";
- public static final String WORKFLOW_FORM_READ = "WORKFLOW_FORM_READ";
+ public static final String USER_REQUEST_FORM_LIST = "USER_REQUEST_FORM_LIST";
- public static final String WORKFLOW_FORM_CLAIM = "WORKFLOW_FORM_CLAIM";
+ public static final String USER_REQUEST_FORM_CLAIM = "USER_REQUEST_FORM_CLAIM";
- public static final String WORKFLOW_FORM_SUBMIT = "WORKFLOW_FORM_SUBMIT";
-
- public static final String USER_REQUEST_DEF_CREATE = "USER_REQUEST_DEF_CREATE";
-
- public static final String USER_REQUEST_DEF_UPDATE = "USER_REQUEST_DEF_UPDATE";
-
- public static final String USER_REQUEST_DEF_DELETE = "USER_REQUEST_DEF_DELETE";
+ public static final String USER_REQUEST_FORM_SUBMIT = "USER_REQUEST_FORM_SUBMIT";
public static final String USER_REQUEST_START = "USER_REQUEST_START";
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/UserRequestFormPropertyType.java
----------------------------------------------------------------------
diff --git a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/UserRequestFormPropertyType.java b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/UserRequestFormPropertyType.java
index 9565f99..227296b 100644
--- a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/UserRequestFormPropertyType.java
+++ b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/UserRequestFormPropertyType.java
@@ -27,6 +27,7 @@ public enum UserRequestFormPropertyType {
Long,
Enum,
Date,
- Boolean
+ Boolean,
+ Dropdown
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/BpmnProcessManager.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/BpmnProcessManager.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/BpmnProcessManager.java
index 9247fd4..f7d1747 100644
--- a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/BpmnProcessManager.java
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/BpmnProcessManager.java
@@ -20,7 +20,7 @@ package org.apache.syncope.core.flowable.api;
import java.io.OutputStream;
import java.util.List;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.common.lib.types.BpmnProcessFormat;
public interface BpmnProcessManager {
@@ -28,7 +28,7 @@ public interface BpmnProcessManager {
/**
* @return all available workflow processes.
*/
- List<BpmnProcessTO> getProcesses();
+ List<BpmnProcess> getProcesses();
/**
* Export the process for the given key, in the requested format.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/DropdownValueProvider.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/DropdownValueProvider.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/DropdownValueProvider.java
new file mode 100644
index 0000000..b6c79cf
--- /dev/null
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/DropdownValueProvider.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.core.flowable.api;
+
+import java.util.Map;
+
+/**
+ * Implementations of this interface are used with {@link org.apache.syncope.core.flowable.support.DropdownFormType}.
+ */
+public interface DropdownValueProvider {
+
+ String NAME = "dropdownValueProvider";
+
+ Map<String, String> getValues();
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/UserRequestHandler.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/UserRequestHandler.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/UserRequestHandler.java
index b11b97c..c3c6f0d 100644
--- a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/UserRequestHandler.java
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/UserRequestHandler.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.flowable.api;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.UserRequestTO;
+import org.apache.syncope.common.lib.to.UserRequest;
import org.apache.syncope.common.lib.to.UserRequestForm;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.entity.user.User;
@@ -33,13 +33,25 @@ import org.springframework.transaction.event.TransactionalEventListener;
public interface UserRequestHandler {
/**
+ * Get the running user requests matching the provided parameters.
+ *
+ * @param userKey user key (optional)
+ * @param page result page
+ * @param size items per page
+ * @param orderByClauses sort conditions
+ * @return total number of user requests, list of user requests matching the provided parameters
+ */
+ Pair<Integer, List<UserRequest>> getUserRequests(
+ String userKey, int page, int size, List<OrderByClause> orderByClauses);
+
+ /**
* Starts a new user request, for the given BPMN process and user.
*
* @param bpmnProcess BPMN process
* @param user user
* @return data about the started request service, including execution id
*/
- UserRequestTO start(String bpmnProcess, User user);
+ UserRequest start(String bpmnProcess, User user);
/**
* Parses the given execution id to find matching user request and owner.
@@ -73,22 +85,16 @@ public interface UserRequestHandler {
void cancelByUser(AnyDeletedEvent event);
/**
- * Get the forms for current workflow process instances matching the provided parameters.
+ * Get the forms matching the provided parameters.
*
+ * @param userKey user key (optional)
* @param page result page
* @param size items per page
* @param orderByClauses sort conditions
* @return total number of forms, list of forms matching the provided parameters
*/
- Pair<Integer, List<UserRequestForm>> getForms(int page, int size, List<OrderByClause> orderByClauses);
-
- /**
- * Get forms for given user (if present).
- *
- * @param userKey user key
- * @return form (if present), otherwise null
- */
- List<UserRequestForm> getForms(String userKey);
+ Pair<Integer, List<UserRequestForm>> getForms(
+ String userKey, int page, int size, List<OrderByClause> orderByClauses);
/**
* Claim a form for a given object.
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableBpmnProcessManager.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableBpmnProcessManager.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableBpmnProcessManager.java
index bca8b25..50b078b 100644
--- a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableBpmnProcessManager.java
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableBpmnProcessManager.java
@@ -28,9 +28,10 @@ import java.io.OutputStream;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.io.IOUtils;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.common.lib.types.BpmnProcessFormat;
import org.apache.syncope.core.flowable.support.DomainProcessEngine;
+import org.apache.syncope.core.flowable.support.DropdownAwareJsonConverter;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.workflow.api.WorkflowException;
import org.flowable.bpmn.converter.BpmnXMLConverter;
@@ -73,11 +74,11 @@ public class FlowableBpmnProcessManager implements BpmnProcessManager {
}
@Override
- public List<BpmnProcessTO> getProcesses() {
+ public List<BpmnProcess> getProcesses() {
try {
return engine.getRepositoryService().createProcessDefinitionQuery().latestVersion().list().stream().
map(procDef -> {
- BpmnProcessTO defTO = new BpmnProcessTO();
+ BpmnProcess defTO = new BpmnProcess();
defTO.setKey(procDef.getKey());
defTO.setName(procDef.getName());
@@ -163,7 +164,7 @@ public class FlowableBpmnProcessManager implements BpmnProcessManager {
"Could not find JSON node " + BpmnJsonConverter.EDITOR_CHILD_SHAPES);
}
- BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(definitionNode);
+ BpmnModel bpmnModel = new DropdownAwareJsonConverter().convertToBpmnModel(definitionNode);
deployment = FlowableDeployUtils.deployDefinition(
engine,
resourceName,
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableRuntimeUtils.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableRuntimeUtils.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableRuntimeUtils.java
index 12d8faa..cdf035d 100644
--- a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableRuntimeUtils.java
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableRuntimeUtils.java
@@ -22,6 +22,7 @@ import java.util.Base64;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.core.flowable.support.DomainProcessEngine;
@@ -33,7 +34,6 @@ import org.apache.syncope.core.workflow.api.WorkflowException;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.impl.RuntimeServiceImpl;
-import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
@@ -97,8 +97,17 @@ public final class FlowableRuntimeUtils {
return procInst == null ? null : procInst.getId();
}
- public static String getProcBusinessKey(final String processDefinitionId, final String userKey) {
- return processDefinitionId + ":" + userKey;
+ public static String getProcBusinessKey(final String procDefId, final String userKey) {
+ return procDefId + ":" + userKey;
+ }
+
+ public static Pair<String, String> splitProcBusinessKey(final String procBusinessKey) {
+ String[] split = procBusinessKey.split(":");
+ if (split == null || split.length != 2) {
+ throw new WorkflowException(new IllegalArgumentException("Unexpected business key: " + procBusinessKey));
+ }
+
+ return Pair.of(split[0], split[1]);
}
public static ProcessDefinition getLatestProcDefByKey(final DomainProcessEngine engine, final String key) {
@@ -111,17 +120,17 @@ public final class FlowableRuntimeUtils {
}
public static Set<String> getPerformedTasks(
- final DomainProcessEngine engine, final String procInstID, final User user) {
+ final DomainProcessEngine engine, final String procInstId, final User user) {
return engine.getHistoryService().createHistoricActivityInstanceQuery().
- executionId(procInstID).
+ executionId(procInstId).
list().stream().
map(HistoricActivityInstance::getActivityId).
collect(Collectors.toSet());
}
- public static void updateStatus(final DomainProcessEngine engine, final String procInstID, final User user) {
- List<Task> tasks = createTaskQuery(engine, false).processInstanceId(procInstID).list();
+ public static void updateStatus(final DomainProcessEngine engine, final String procInstId, final User user) {
+ List<Task> tasks = createTaskQuery(engine, false).processInstanceId(procInstId).list();
if (tasks.isEmpty() || tasks.size() > 1) {
LOG.warn("While setting user status: unexpected task number ({})", tasks.size());
} else {
@@ -129,13 +138,6 @@ public final class FlowableRuntimeUtils {
}
}
- public static List<ProcessInstance> getProcessInstances(final DomainProcessEngine engine, final String userKey) {
- return engine.getRuntimeService().createNativeProcessInstanceQuery().
- sql("SELECT ID_,PROC_INST_ID_ FROM " + engine.getManagementService().getTableName(ExecutionEntity.class)
- + " WHERE BUSINESS_KEY_ LIKE '" + getProcBusinessKey("%", userKey) + "'"
- + " AND PARENT_ID_ IS NULL").list();
- }
-
public static TaskQuery createTaskQuery(final DomainProcessEngine engine, final boolean onlyFormTasks) {
SyncopeTaskQueryImpl taskQuery = new SyncopeTaskQueryImpl(
((RuntimeServiceImpl) engine.getRuntimeService()).getCommandExecutor());
@@ -145,10 +147,10 @@ public final class FlowableRuntimeUtils {
return taskQuery;
}
- public static String getFormTask(final DomainProcessEngine engine, final String procInstID) {
+ public static String getFormTask(final DomainProcessEngine engine, final String procInstId) {
String result = null;
- List<Task> tasks = createTaskQuery(engine, true).processInstanceId(procInstID).list();
+ List<Task> tasks = createTaskQuery(engine, true).processInstanceId(procInstId).list();
if (tasks.isEmpty() || tasks.size() > 1) {
LOG.debug("While checking if form task: unexpected task number ({})", tasks.size());
} else {
@@ -162,7 +164,7 @@ public final class FlowableRuntimeUtils {
* Saves resources to be propagated and password for later - after form submission - propagation.
*
* @param engine Flowable engine
- * @param procInstID process instance id
+ * @param procInstId process instance id
* @param user user JPA entity
* @param userTO user transfer object
* @param password password
@@ -171,35 +173,35 @@ public final class FlowableRuntimeUtils {
*/
public static void saveForFormSubmit(
final DomainProcessEngine engine,
- final String procInstID,
+ final String procInstId,
final User user,
final UserTO userTO,
final String password,
final Boolean enabled,
final PropagationByResource propByRes) {
- String formTaskId = getFormTask(engine, procInstID);
+ String formTaskId = getFormTask(engine, procInstId);
if (formTaskId == null) {
return;
}
- engine.getRuntimeService().setVariable(procInstID, FlowableRuntimeUtils.USER_TO, userTO);
+ engine.getRuntimeService().setVariable(procInstId, FlowableRuntimeUtils.USER_TO, userTO);
if (password == null) {
String encryptedPwd = engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.ENCRYPTED_PWD, String.class);
+ getVariable(procInstId, FlowableRuntimeUtils.ENCRYPTED_PWD, String.class);
if (encryptedPwd != null) {
userTO.setPassword(decrypt(encryptedPwd));
}
} else {
userTO.setPassword(password);
engine.getRuntimeService().
- setVariable(procInstID, FlowableRuntimeUtils.ENCRYPTED_PWD, encrypt(password));
+ setVariable(procInstId, FlowableRuntimeUtils.ENCRYPTED_PWD, encrypt(password));
}
- engine.getRuntimeService().setVariable(procInstID, FlowableRuntimeUtils.ENABLED, enabled);
+ engine.getRuntimeService().setVariable(procInstId, FlowableRuntimeUtils.ENABLED, enabled);
- engine.getRuntimeService().setVariable(procInstID, FlowableRuntimeUtils.PROP_BY_RESOURCE, propByRes);
+ engine.getRuntimeService().setVariable(procInstId, FlowableRuntimeUtils.PROP_BY_RESOURCE, propByRes);
if (propByRes != null) {
propByRes.clear();
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserRequestHandler.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserRequestHandler.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserRequestHandler.java
index 1c198a8..45a834b 100644
--- a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserRequestHandler.java
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserRequestHandler.java
@@ -31,13 +31,14 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.patch.PasswordPatch;
import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.UserRequestTO;
+import org.apache.syncope.common.lib.to.UserRequest;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.to.UserRequestFormProperty;
import org.apache.syncope.common.lib.to.UserRequestForm;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ResourceOperation;
import org.apache.syncope.common.lib.types.UserRequestFormPropertyType;
+import org.apache.syncope.core.flowable.api.DropdownValueProvider;
import org.apache.syncope.core.flowable.api.WorkflowTaskManager;
import org.apache.syncope.core.flowable.support.DomainProcessEngine;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
@@ -49,16 +50,21 @@ import org.apache.syncope.core.provisioning.api.PropagationByResource;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
import org.apache.syncope.core.provisioning.api.event.AnyDeletedEvent;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.spring.BeanUtils;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.core.workflow.api.WorkflowException;
import org.flowable.common.engine.api.FlowableException;
+import org.flowable.common.engine.api.FlowableIllegalArgumentException;
import org.flowable.engine.form.FormProperty;
import org.flowable.engine.form.FormType;
import org.flowable.engine.form.TaskFormData;
import org.flowable.engine.history.HistoricActivityInstance;
+import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.persistence.entity.HistoricFormPropertyEntity;
+import org.flowable.engine.runtime.NativeProcessInstanceQuery;
import org.flowable.engine.runtime.ProcessInstance;
+import org.flowable.engine.runtime.ProcessInstanceQuery;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.flowable.task.api.history.HistoricTaskInstance;
@@ -93,6 +99,93 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
@Autowired
protected EntityFactory entityFactory;
+ protected NativeProcessInstanceQuery createProcessInstanceQuery(final String userKey) {
+ return engine.getRuntimeService().createNativeProcessInstanceQuery().
+ sql("SELECT DISTINCT ID_,BUSINESS_KEY_,ACT_ID_ FROM "
+ + engine.getManagementService().getTableName(ExecutionEntity.class)
+ + " WHERE BUSINESS_KEY_ LIKE '"
+ + FlowableRuntimeUtils.getProcBusinessKey("%", userKey) + "'"
+ + " AND BUSINESS_KEY_ NOT LIKE '"
+ + FlowableRuntimeUtils.getProcBusinessKey(FlowableRuntimeUtils.WF_PROCESS_ID, "%") + "'"
+ + " AND PARENT_ID_ IS NULL");
+ }
+
+ protected int countProcessInstances(final String userKey) {
+ return (int) engine.getRuntimeService().createNativeProcessInstanceQuery().
+ sql("SELECT COUNT(ID_) FROM "
+ + engine.getManagementService().getTableName(ExecutionEntity.class)
+ + " WHERE BUSINESS_KEY_ LIKE '"
+ + FlowableRuntimeUtils.getProcBusinessKey("%", userKey) + "'"
+ + " AND BUSINESS_KEY_ NOT LIKE '"
+ + FlowableRuntimeUtils.getProcBusinessKey(FlowableRuntimeUtils.WF_PROCESS_ID, "%") + "'"
+ + " AND PARENT_ID_ IS NULL").count();
+ }
+
+ protected UserRequest getUserRequest(final ProcessInstance procInst) {
+ Pair<String, String> split = FlowableRuntimeUtils.splitProcBusinessKey(procInst.getBusinessKey());
+
+ UserRequest userRequest = new UserRequest();
+ userRequest.setBpmnProcess(split.getLeft());
+ userRequest.setUser(split.getRight());
+ userRequest.setExecutionId(procInst.getId());
+ userRequest.setActivityId(procInst.getActivityId());
+ return userRequest;
+ }
+
+ @Transactional(readOnly = true)
+ @Override
+ public Pair<Integer, List<UserRequest>> getUserRequests(
+ final String userKey,
+ final int page,
+ final int size,
+ final List<OrderByClause> orderByClauses) {
+
+ Integer count = null;
+ List<UserRequest> result = null;
+ if (userKey == null) {
+ ProcessInstanceQuery query = engine.getRuntimeService().createProcessInstanceQuery().active();
+ for (OrderByClause clause : orderByClauses) {
+ boolean sorted = true;
+ switch (clause.getField().trim()) {
+ case "processDefinitionId":
+ query.orderByProcessDefinitionId();
+ break;
+
+ case "processDefinitionKey":
+ query.orderByProcessDefinitionKey();
+ break;
+
+ case "processInstanceId":
+ query.orderByProcessInstanceId();
+ break;
+
+ default:
+ LOG.warn("User request sort request by {}: unsupported, ignoring", clause.getField().trim());
+ sorted = false;
+ }
+ if (sorted) {
+ if (clause.getDirection() == OrderByClause.Direction.ASC) {
+ query.asc();
+ } else {
+ query.desc();
+ }
+ }
+
+ count = (int) query.count();
+ result = query.listPage(size * (page <= 0 ? 0 : page - 1), size).stream().
+ map(procInst -> getUserRequest(procInst)).
+ collect(Collectors.toList());
+ }
+ } else {
+ count = countProcessInstances(userKey);
+ result = createProcessInstanceQuery(userKey).listPage(size * (page <= 0 ? 0 : page - 1), size).stream().
+ map(procInst -> getUserRequest(procInst)).
+ collect(Collectors.toList());
+ }
+
+ return Pair.of(count, result);
+ }
+
protected User lazyLoad(final User user) {
// 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
@@ -101,8 +194,8 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
}
@Override
- public UserRequestTO start(final String bpmnProcess, final User user) {
- Map<String, Object> variables = new HashMap<>(2);
+ public UserRequest start(final String bpmnProcess, final User user) {
+ Map<String, Object> variables = new HashMap<>();
variables.put(FlowableRuntimeUtils.WF_EXECUTOR, AuthContextUtils.getUsername());
variables.put(FlowableRuntimeUtils.USER, lazyLoad(user));
variables.put(FlowableRuntimeUtils.USER_TO, dataBinder.getUserTO(user, true));
@@ -118,12 +211,8 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
procInst.getProcessInstanceId(),
FlowableRuntimeUtils.getProcBusinessKey(bpmnProcess, user.getKey()));
- UserRequestTO userRequestTO = new UserRequestTO();
- userRequestTO.setProcessInstanceId(procInst.getProcessInstanceId());
- userRequestTO.setExecutionId(procInst.getId());
- userRequestTO.setBpmnProcess(bpmnProcess);
- userRequestTO.setUser(user.getKey());
- return userRequestTO;
+ return getUserRequest(engine.getRuntimeService().createProcessInstanceQuery().
+ processInstanceId(procInst.getProcessInstanceId()).singleResult());
}
@Override
@@ -132,7 +221,11 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
try {
procInst = engine.getRuntimeService().
createProcessInstanceQuery().processInstanceId(executionId).singleResult();
+ if (procInst == null) {
+ throw new FlowableIllegalArgumentException("ProcessInstance with id " + executionId);
+ }
} catch (FlowableException e) {
+ LOG.error("Could find execution ProcessInstance with id {}", executionId, e);
throw new NotFoundException("User request execution with id " + executionId);
}
@@ -163,7 +256,7 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
public void cancelByUser(final AnyDeletedEvent event) {
if (AuthContextUtils.getDomain().equals(event.getDomain()) && event.getAnyTypeKind() == AnyTypeKind.USER) {
String username = event.getAnyName();
- FlowableRuntimeUtils.getProcessInstances(engine, event.getAnyKey()).
+ createProcessInstanceQuery(event.getAnyKey()).list().
forEach(procInst -> {
engine.getRuntimeService().deleteProcessInstance(
procInst.getId(), "Cascade Delete user " + username);
@@ -192,6 +285,10 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
result = UserRequestFormPropertyType.Boolean;
break;
+ case "dropdown":
+ result = UserRequestFormPropertyType.Dropdown;
+ break;
+
case "string":
default:
break;
@@ -201,19 +298,19 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
return result;
}
- protected UserRequestForm getFormTO(final Task task) {
- return getFormTO(task, engine.getFormService().getTaskFormData(task.getId()));
+ protected UserRequestForm getForm(final Task task) {
+ return FlowableUserRequestHandler.this.getForm(task, engine.getFormService().getTaskFormData(task.getId()));
}
- protected UserRequestForm getFormTO(final Task task, final TaskFormData fd) {
+ protected UserRequestForm getForm(final Task task, final TaskFormData fd) {
UserRequestForm formTO =
- getFormTO(task.getProcessInstanceId(), task.getId(), fd.getFormKey(), fd.getFormProperties());
+ getForm(task.getProcessInstanceId(), task.getId(), fd.getFormKey(), fd.getFormProperties());
BeanUtils.copyProperties(task, formTO);
return formTO;
}
- protected UserRequestForm getFormTO(final HistoricTaskInstance task) {
+ protected UserRequestForm getForm(final HistoricTaskInstance task) {
List<HistoricFormPropertyEntity> props = engine.getHistoryService().
createHistoricDetailQuery().taskId(task.getId()).list().stream().
filter(HistoricFormPropertyEntity.class::isInstance).
@@ -244,16 +341,19 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
}
protected UserRequestForm getHistoricFormTO(
- final String procInstID,
+ final String procInstId,
final String taskId,
final String formKey,
final List<HistoricFormPropertyEntity> props) {
UserRequestForm formTO = new UserRequestForm();
- User user = userDAO.find(getUserKey(procInstID));
+ formTO.setBpmnProcess(engine.getRuntimeService().createProcessInstanceQuery().
+ processInstanceId(procInstId).singleResult().getProcessDefinitionKey());
+
+ User user = userDAO.find(getUserKey(procInstId));
if (user == null) {
- throw new NotFoundException("User for process instance id " + procInstID);
+ throw new NotFoundException("User for process instance id " + procInstId);
}
formTO.setUsername(user.getUsername());
@@ -261,9 +361,9 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
formTO.setFormKey(formKey);
formTO.setUserTO(engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.USER_TO, UserTO.class));
+ getVariable(procInstId, FlowableRuntimeUtils.USER_TO, UserTO.class));
formTO.setUserPatch(engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.USER_PATCH, UserPatch.class));
+ getVariable(procInstId, FlowableRuntimeUtils.USER_PATCH, UserPatch.class));
formTO.getProperties().addAll(props.stream().map(prop -> {
UserRequestFormProperty propertyTO = new UserRequestFormProperty();
@@ -277,37 +377,58 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
}
@SuppressWarnings("unchecked")
- protected UserRequestForm getFormTO(
- final String procInstID,
+ protected UserRequestForm getForm(
+ final String procInstId,
final String taskId,
final String formKey,
final List<FormProperty> props) {
UserRequestForm formTO = new UserRequestForm();
- User user = userDAO.find(getUserKey(procInstID));
+ formTO.setBpmnProcess(engine.getRuntimeService().createProcessInstanceQuery().
+ processInstanceId(procInstId).singleResult().getProcessDefinitionKey());
+
+ User user = userDAO.find(getUserKey(procInstId));
if (user == null) {
- throw new NotFoundException("User for process instance id " + procInstID);
+ throw new NotFoundException("User for process instance id " + procInstId);
}
formTO.setUsername(user.getUsername());
+ formTO.setExecutionId(procInstId);
formTO.setTaskId(taskId);
formTO.setFormKey(formKey);
formTO.setUserTO(engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.USER_TO, UserTO.class));
+ getVariable(procInstId, FlowableRuntimeUtils.USER_TO, UserTO.class));
formTO.setUserPatch(engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.USER_PATCH, UserPatch.class));
+ getVariable(procInstId, FlowableRuntimeUtils.USER_PATCH, UserPatch.class));
formTO.getProperties().addAll(props.stream().map(fProp -> {
UserRequestFormProperty propertyTO = new UserRequestFormProperty();
BeanUtils.copyProperties(fProp, propertyTO, PROPERTY_IGNORE_PROPS);
propertyTO.setType(fromFlowableFormType(fProp.getType()));
- if (propertyTO.getType() == UserRequestFormPropertyType.Date) {
- propertyTO.setDatePattern((String) fProp.getType().getInformation("datePattern"));
- }
- if (propertyTO.getType() == UserRequestFormPropertyType.Enum) {
- propertyTO.getEnumValues().putAll((Map<String, String>) fProp.getType().getInformation("values"));
+ switch (propertyTO.getType()) {
+ case Date:
+ propertyTO.setDatePattern((String) fProp.getType().getInformation("datePattern"));
+ break;
+
+ case Enum:
+ propertyTO.getEnumValues().putAll((Map<String, String>) fProp.getType().getInformation("values"));
+ break;
+
+ case Dropdown:
+ String valueProviderBean = (String) fProp.getType().getInformation(DropdownValueProvider.NAME);
+ try {
+ DropdownValueProvider valueProvider = ApplicationContextProvider.getApplicationContext().
+ getBean(valueProviderBean, DropdownValueProvider.class);
+ propertyTO.getDropdownValues().putAll(valueProvider.getValues());
+ } catch (Exception e) {
+ LOG.error("Could not find bean {} of type {} for form property {}",
+ valueProviderBean, DropdownValueProvider.class.getName(), propertyTO.getId(), e);
+ }
+ break;
+
+ default:
}
return propertyTO;
}).collect(Collectors.toList()));
@@ -318,26 +439,28 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
@Transactional(readOnly = true)
@Override
public Pair<Integer, List<UserRequestForm>> getForms(
- final int page, final int size, final List<OrderByClause> orderByClauses) {
+ final String userKey,
+ final int page,
+ final int size,
+ final List<OrderByClause> orderByClauses) {
- Pair<Integer, List<UserRequestForm>> forms = null;
+ Pair<Integer, List<UserRequestForm>> forms;
- TaskQuery formTaskQuery = FlowableRuntimeUtils.createTaskQuery(engine, true);
+ TaskQuery query = FlowableRuntimeUtils.createTaskQuery(engine, true);
+ if (userKey != null) {
+ query.processInstanceBusinessKeyLike(FlowableRuntimeUtils.getProcBusinessKey("%", userKey));
+ }
String authUser = AuthContextUtils.getUsername();
if (adminUser.equals(authUser)) {
- forms = getForms(formTaskQuery, page, size, orderByClauses);
+ forms = getForms(query, page, size, orderByClauses);
} else {
User user = userDAO.findByUsername(authUser);
- if (user == null) {
- throw new NotFoundException("Syncope User " + authUser);
- }
-
- forms = getForms(formTaskQuery.taskCandidateOrAssigned(user.getUsername()), page, size, orderByClauses);
+ forms = getForms(query.taskCandidateOrAssigned(user.getUsername()), page, size, orderByClauses);
List<String> candidateGroups = new ArrayList<>(userDAO.findAllGroupNames(user));
if (!candidateGroups.isEmpty()) {
- forms = getForms(formTaskQuery.taskCandidateGroupIn(candidateGroups), page, size, orderByClauses);
+ forms = getForms(query.taskCandidateGroupIn(candidateGroups), page, size, orderByClauses);
}
}
@@ -349,75 +472,56 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
protected Pair<Integer, List<UserRequestForm>> getForms(
final TaskQuery query, final int page, final int size, final List<OrderByClause> orderByClauses) {
- TaskQuery sortedQuery = query;
for (OrderByClause clause : orderByClauses) {
- boolean ack = true;
+ boolean sorted = true;
switch (clause.getField().trim()) {
+ case "bpmnProcess":
+ query.orderByProcessDefinitionId();
+ break;
+
+ case "executionId":
+ query.orderByExecutionId();
+ break;
+
case "taskId":
- sortedQuery = sortedQuery.orderByTaskId();
+ query.orderByTaskId();
break;
case "createTime":
- sortedQuery = sortedQuery.orderByTaskCreateTime();
+ query.orderByTaskCreateTime();
break;
case "dueDate":
- sortedQuery = sortedQuery.orderByTaskDueDate();
+ query.orderByTaskDueDate();
break;
case "owner":
- sortedQuery = sortedQuery.orderByTaskOwner();
+ query.orderByTaskOwner();
break;
default:
LOG.warn("Form sort request by {}: unsupported, ignoring", clause.getField().trim());
- ack = false;
+ sorted = false;
}
- if (ack) {
- sortedQuery = clause.getDirection() == OrderByClause.Direction.ASC
- ? sortedQuery.asc()
- : sortedQuery.desc();
+ if (sorted) {
+ if (clause.getDirection() == OrderByClause.Direction.ASC) {
+ query.asc();
+ } else {
+ query.desc();
+ }
}
}
- List<UserRequestForm> result = sortedQuery.listPage(size * (page <= 0 ? 0 : page - 1), size).stream().
+ List<UserRequestForm> result = query.listPage(size * (page <= 0 ? 0 : page - 1), size).stream().
map(task -> task instanceof HistoricTaskInstance
- ? getFormTO((HistoricTaskInstance) task) : getFormTO(task)).
+ ? FlowableUserRequestHandler.this.getForm((HistoricTaskInstance) task)
+ : FlowableUserRequestHandler.this.getForm(task)).
collect(Collectors.toList());
return Pair.of((int) query.count(), result);
}
- @Override
- public List<UserRequestForm> getForms(final String userKey) {
- List<UserRequestForm> result = new ArrayList<>();
- FlowableRuntimeUtils.getProcessInstances(engine, userKey).forEach(procInst -> {
- Task task;
- try {
- task = FlowableRuntimeUtils.createTaskQuery(engine, true).
- processInstanceId(procInst.getProcessInstanceId()).singleResult();
- } catch (FlowableException e) {
- throw new WorkflowException("While reading form for process instance "
- + procInst.getProcessInstanceId(), e);
- }
-
- if (task != null) {
- TaskFormData formData;
- try {
- formData = engine.getFormService().getTaskFormData(task.getId());
- } catch (FlowableException e) {
- throw new WorkflowException("Error while getting form data for task " + task.getId(), e);
- }
- if (formData != null && !formData.getFormProperties().isEmpty()) {
- result.add(getFormTO(task, formData));
- }
- }
- });
-
- return result;
- }
-
- protected Pair<Task, TaskFormData> checkTask(final String taskId, final String authUser) {
+ protected Pair<Task, TaskFormData> parseTask(final String taskId) {
Task task;
try {
task = FlowableRuntimeUtils.createTaskQuery(engine, true).taskId(taskId).singleResult();
@@ -435,27 +539,20 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
throw new NotFoundException("Form for Flowable Task " + taskId, e);
}
- if (!adminUser.equals(authUser)) {
- User user = userDAO.findByUsername(authUser);
- if (user == null) {
- throw new NotFoundException("Syncope User " + authUser);
- }
- }
-
return Pair.of(task, formData);
}
@Override
public UserRequestForm claimForm(final String taskId) {
- String authUser = AuthContextUtils.getUsername();
- Pair<Task, TaskFormData> checked = checkTask(taskId, authUser);
+ Pair<Task, TaskFormData> parsed = parseTask(taskId);
+ String authUser = AuthContextUtils.getUsername();
if (!adminUser.equals(authUser)) {
List<Task> tasksForUser = FlowableRuntimeUtils.createTaskQuery(engine, true).
- taskId(taskId).taskCandidateUser(authUser).list();
+ taskId(taskId).taskCandidateOrAssigned(authUser).list();
if (tasksForUser.isEmpty()) {
throw new WorkflowException(
- new IllegalArgumentException(authUser + " is not candidate for task " + taskId));
+ new IllegalArgumentException(authUser + " is not candidate nor assignee of task " + taskId));
}
}
@@ -467,7 +564,7 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
throw new WorkflowException("While reading task " + taskId, e);
}
- return getFormTO(task, checked.getRight());
+ return FlowableUserRequestHandler.this.getForm(task, parsed.getRight());
}
private Map<String, String> getPropertiesForSubmit(final UserRequestForm form) {
@@ -482,36 +579,36 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
@Override
public WorkflowResult<UserPatch> submitForm(final UserRequestForm form) {
- String authUser = AuthContextUtils.getUsername();
- Pair<Task, TaskFormData> checked = checkTask(form.getTaskId(), authUser);
+ Pair<Task, TaskFormData> parsed = parseTask(form.getTaskId());
- if (!checked.getLeft().getOwner().equals(authUser)) {
+ String authUser = AuthContextUtils.getUsername();
+ if (!parsed.getLeft().getOwner().equals(authUser)) {
throw new WorkflowException(new IllegalArgumentException("Task " + form.getTaskId() + " assigned to "
- + checked.getLeft().getOwner() + " but submitted by " + authUser));
+ + parsed.getLeft().getOwner() + " but submitted by " + authUser));
}
- String procInstID = checked.getLeft().getProcessInstanceId();
+ String procInstId = parsed.getLeft().getProcessInstanceId();
- User user = userDAO.find(getUserKey(procInstID));
+ User user = userDAO.find(getUserKey(procInstId));
if (user == null) {
- throw new NotFoundException("User with key " + getUserKey(procInstID));
+ throw new NotFoundException("User with key " + getUserKey(procInstId));
}
- Set<String> preTasks = FlowableRuntimeUtils.getPerformedTasks(engine, procInstID, user);
+ Set<String> preTasks = FlowableRuntimeUtils.getPerformedTasks(engine, procInstId, user);
- engine.getRuntimeService().setVariable(procInstID, FlowableRuntimeUtils.TASK, "submit");
- engine.getRuntimeService().setVariable(procInstID, FlowableRuntimeUtils.FORM_SUBMITTER, authUser);
- engine.getRuntimeService().setVariable(procInstID, FlowableRuntimeUtils.USER, lazyLoad(user));
+ engine.getRuntimeService().setVariable(procInstId, FlowableRuntimeUtils.TASK, "submit");
+ engine.getRuntimeService().setVariable(procInstId, FlowableRuntimeUtils.FORM_SUBMITTER, authUser);
+ engine.getRuntimeService().setVariable(procInstId, FlowableRuntimeUtils.USER, lazyLoad(user));
try {
engine.getFormService().submitTaskFormData(form.getTaskId(), getPropertiesForSubmit(form));
} catch (FlowableException e) {
FlowableRuntimeUtils.throwException(e, "While submitting form for task " + form.getTaskId());
}
- Set<String> postTasks = FlowableRuntimeUtils.getPerformedTasks(engine, procInstID, user);
+ Set<String> postTasks = FlowableRuntimeUtils.getPerformedTasks(engine, procInstId, user);
postTasks.removeAll(preTasks);
postTasks.add(form.getTaskId());
- if (procInstID.equals(FlowableRuntimeUtils.getWFProcInstID(engine, user.getKey()))) {
- FlowableRuntimeUtils.updateStatus(engine, procInstID, user);
+ if (procInstId.equals(FlowableRuntimeUtils.getWFProcInstID(engine, user.getKey()))) {
+ FlowableRuntimeUtils.updateStatus(engine, procInstId, user);
}
user = userDAO.save(user);
@@ -521,34 +618,34 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
PropagationByResource propByRes = null;
ProcessInstance afterSubmitPI = engine.getRuntimeService().
- createProcessInstanceQuery().processInstanceId(procInstID).singleResult();
+ createProcessInstanceQuery().processInstanceId(procInstId).singleResult();
if (afterSubmitPI != null) {
- engine.getRuntimeService().removeVariable(procInstID, FlowableRuntimeUtils.TASK);
- engine.getRuntimeService().removeVariable(procInstID, FlowableRuntimeUtils.FORM_SUBMITTER);
- engine.getRuntimeService().removeVariable(procInstID, FlowableRuntimeUtils.USER);
- engine.getRuntimeService().removeVariable(procInstID, FlowableRuntimeUtils.USER_TO);
+ engine.getRuntimeService().removeVariable(procInstId, FlowableRuntimeUtils.TASK);
+ engine.getRuntimeService().removeVariable(procInstId, FlowableRuntimeUtils.FORM_SUBMITTER);
+ engine.getRuntimeService().removeVariable(procInstId, FlowableRuntimeUtils.USER);
+ engine.getRuntimeService().removeVariable(procInstId, FlowableRuntimeUtils.USER_TO);
// see if there is any propagation to be done
propByRes = engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.PROP_BY_RESOURCE, PropagationByResource.class);
- engine.getRuntimeService().removeVariable(procInstID, FlowableRuntimeUtils.PROP_BY_RESOURCE);
+ getVariable(procInstId, FlowableRuntimeUtils.PROP_BY_RESOURCE, PropagationByResource.class);
+ engine.getRuntimeService().removeVariable(procInstId, FlowableRuntimeUtils.PROP_BY_RESOURCE);
// fetch - if available - the encrypted password
String encryptedPwd = engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.ENCRYPTED_PWD, String.class);
- engine.getRuntimeService().removeVariable(procInstID, FlowableRuntimeUtils.ENCRYPTED_PWD);
+ getVariable(procInstId, FlowableRuntimeUtils.ENCRYPTED_PWD, String.class);
+ engine.getRuntimeService().removeVariable(procInstId, FlowableRuntimeUtils.ENCRYPTED_PWD);
if (StringUtils.isNotBlank(encryptedPwd)) {
clearPassword = FlowableRuntimeUtils.decrypt(encryptedPwd);
}
Boolean enabled = engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.ENABLED, Boolean.class);
- engine.getRuntimeService().removeVariable(procInstID, FlowableRuntimeUtils.ENABLED);
+ getVariable(procInstId, FlowableRuntimeUtils.ENABLED, Boolean.class);
+ engine.getRuntimeService().removeVariable(procInstId, FlowableRuntimeUtils.ENABLED);
// supports approval chains
FlowableRuntimeUtils.saveForFormSubmit(
engine,
- procInstID,
+ procInstId,
user,
dataBinder.getUserTO(user, true),
clearPassword,
@@ -556,8 +653,8 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
propByRes);
userPatch = engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.USER_PATCH, UserPatch.class);
- engine.getRuntimeService().removeVariable(procInstID, FlowableRuntimeUtils.USER_PATCH);
+ getVariable(procInstId, FlowableRuntimeUtils.USER_PATCH, UserPatch.class);
+ engine.getRuntimeService().removeVariable(procInstId, FlowableRuntimeUtils.USER_PATCH);
}
if (userPatch == null) {
userPatch = new UserPatch();
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DomainProcessEngineFactoryBean.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DomainProcessEngineFactoryBean.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DomainProcessEngineFactoryBean.java
index 162b113..de2bbfe 100644
--- a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DomainProcessEngineFactoryBean.java
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DomainProcessEngineFactoryBean.java
@@ -18,13 +18,16 @@
*/
package org.apache.syncope.core.flowable.support;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.ProcessEngine;
import org.flowable.common.engine.impl.cfg.SpringBeanFactoryProxyMap;
import org.flowable.common.engine.impl.interceptor.EngineConfigurationConstants;
+import org.flowable.engine.form.AbstractFormType;
import org.flowable.engine.impl.util.EngineServiceUtil;
import org.flowable.idm.spring.SpringIdmEngineConfiguration;
import org.flowable.spring.SpringExpressionManager;
@@ -81,6 +84,9 @@ public class DomainProcessEngineFactoryBean
EngineConfigurationConstants.KEY_IDM_ENGINE_CONFIG,
ctx.getBean(SpringIdmEngineConfiguration.class));
}
+ List<AbstractFormType> customFormTypes = new ArrayList<>();
+ customFormTypes.add(new DropdownFormType(null));
+ conf.setCustomFormTypes(customFormTypes);
engines.put(domain, conf.buildProcessEngine());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownAwareJsonConverter.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownAwareJsonConverter.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownAwareJsonConverter.java
new file mode 100644
index 0000000..ad29e17
--- /dev/null
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownAwareJsonConverter.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.core.flowable.support;
+
+import org.flowable.bpmn.model.UserTask;
+import org.flowable.editor.constants.StencilConstants;
+import org.flowable.editor.language.json.converter.BpmnJsonConverter;
+
+public class DropdownAwareJsonConverter extends BpmnJsonConverter {
+
+ public DropdownAwareJsonConverter() {
+ convertersToBpmnMap.put(StencilConstants.STENCIL_TASK_USER, DropdownAwareUserTaskJsonConverter.class);
+ convertersToJsonMap.put(UserTask.class, DropdownAwareUserTaskJsonConverter.class);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownAwareUserTaskJsonConverter.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownAwareUserTaskJsonConverter.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownAwareUserTaskJsonConverter.java
new file mode 100644
index 0000000..838201c
--- /dev/null
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownAwareUserTaskJsonConverter.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.flowable.support;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.flowable.bpmn.model.BaseElement;
+import org.flowable.bpmn.model.FormProperty;
+import org.flowable.bpmn.model.FormValue;
+import org.flowable.bpmn.model.StartEvent;
+import org.flowable.bpmn.model.UserTask;
+import org.flowable.editor.language.json.converter.BpmnJsonConverterUtil;
+import org.flowable.editor.language.json.converter.UserTaskJsonConverter;
+
+public class DropdownAwareUserTaskJsonConverter extends UserTaskJsonConverter {
+
+ @Override
+ protected void convertJsonToFormProperties(final JsonNode objectNode, final BaseElement element) {
+ JsonNode formPropertiesNode = getProperty(PROPERTY_FORM_PROPERTIES, objectNode);
+ if (formPropertiesNode != null) {
+ formPropertiesNode = BpmnJsonConverterUtil.validateIfNodeIsTextual(formPropertiesNode);
+ JsonNode propertiesArray = formPropertiesNode.get("formProperties");
+ if (propertiesArray != null) {
+ for (JsonNode formNode : propertiesArray) {
+ JsonNode formIdNode = formNode.get(PROPERTY_FORM_ID);
+ if (formIdNode != null && StringUtils.isNotEmpty(formIdNode.asText())) {
+
+ FormProperty formProperty = new FormProperty();
+ formProperty.setId(formIdNode.asText());
+ formProperty.setName(getValueAsString(PROPERTY_FORM_NAME, formNode));
+ formProperty.setType(getValueAsString(PROPERTY_FORM_TYPE, formNode));
+ formProperty.setExpression(getValueAsString(PROPERTY_FORM_EXPRESSION, formNode));
+ formProperty.setVariable(getValueAsString(PROPERTY_FORM_VARIABLE, formNode));
+
+ if ("date".equalsIgnoreCase(formProperty.getType())) {
+ formProperty.setDatePattern(getValueAsString(PROPERTY_FORM_DATE_PATTERN, formNode));
+
+ } else if ("enum".equalsIgnoreCase(formProperty.getType())
+ || "dropdown".equalsIgnoreCase(formProperty.getType())) {
+
+ JsonNode enumValuesNode = formNode.get(PROPERTY_FORM_ENUM_VALUES);
+ if (enumValuesNode != null) {
+ List<FormValue> formValueList = new ArrayList<>();
+ for (JsonNode enumNode : enumValuesNode) {
+ if (enumNode.get(PROPERTY_FORM_ENUM_VALUES_ID) != null && !enumNode.get(
+ PROPERTY_FORM_ENUM_VALUES_ID).isNull() && enumNode.get(
+ PROPERTY_FORM_ENUM_VALUES_NAME) != null
+ && !enumNode.get(PROPERTY_FORM_ENUM_VALUES_NAME).isNull()) {
+
+ FormValue formValue = new FormValue();
+ formValue.setId(enumNode.get(PROPERTY_FORM_ENUM_VALUES_ID).asText());
+ formValue.setName(enumNode.get(PROPERTY_FORM_ENUM_VALUES_NAME).asText());
+ formValueList.add(formValue);
+
+ } else if (enumNode.get("value") != null && !enumNode.get("value").isNull()) {
+ FormValue formValue = new FormValue();
+ formValue.setId(enumNode.get("value").asText());
+ formValue.setName(enumNode.get("value").asText());
+ formValueList.add(formValue);
+ }
+ }
+ formProperty.setFormValues(formValueList);
+ }
+ }
+
+ formProperty.setRequired(getValueAsBoolean(PROPERTY_FORM_REQUIRED, formNode));
+ formProperty.setReadable(getValueAsBoolean(PROPERTY_FORM_READABLE, formNode));
+ formProperty.setWriteable(getValueAsBoolean(PROPERTY_FORM_WRITABLE, formNode));
+
+ if (element instanceof StartEvent) {
+ ((StartEvent) element).getFormProperties().add(formProperty);
+ } else if (element instanceof UserTask) {
+ ((UserTask) element).getFormProperties().add(formProperty);
+ }
+ }
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownFormType.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownFormType.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownFormType.java
new file mode 100644
index 0000000..6c612f6
--- /dev/null
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownFormType.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.flowable.support;
+
+import org.flowable.engine.form.AbstractFormType;
+
+/**
+ * Extension to predefined Flowable form types relying on the provided
+ * {@link org.apache.syncope.core.flowable.api.DropdownValueProvider} bean to populate values.
+ */
+public class DropdownFormType extends AbstractFormType {
+
+ private static final long serialVersionUID = -3549337216346168946L;
+
+ protected final String dropdownValueProvider;
+
+ public DropdownFormType(final String dropdownValueProvider) {
+ this.dropdownValueProvider = dropdownValueProvider;
+ }
+
+ @Override
+ public String getName() {
+ return "dropdown";
+ }
+
+ @Override
+ public Object getInformation(final String key) {
+ if (key.equals("dropdownValueProvider")) {
+ return dropdownValueProvider;
+ }
+ return null;
+ }
+
+ @Override
+ public Object convertFormValueToModelValue(final String propertyValue) {
+ return propertyValue;
+ }
+
+ @Override
+ public String convertModelValueToFormValue(final Object modelValue) {
+ return modelValue == null ? null : modelValue.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/SyncopeFormHandlerHelper.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/SyncopeFormHandlerHelper.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/SyncopeFormHandlerHelper.java
new file mode 100644
index 0000000..9f6e751
--- /dev/null
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/SyncopeFormHandlerHelper.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.flowable.support;
+
+import org.flowable.bpmn.model.FlowElement;
+import org.flowable.bpmn.model.UserTask;
+import org.flowable.bpmn.model.Process;
+import org.flowable.engine.impl.form.FormHandlerHelper;
+import org.flowable.engine.impl.form.TaskFormHandler;
+import org.flowable.engine.impl.persistence.entity.DeploymentEntity;
+import org.flowable.engine.impl.util.CommandContextUtil;
+import org.flowable.engine.impl.util.ProcessDefinitionUtil;
+import org.flowable.engine.repository.ProcessDefinition;
+
+/**
+ * Used to inject {@link SyncopeTaskFormHandler} rather than
+ * {@link org.flowable.engine.impl.form.DefaultTaskFormHandler}.
+ */
+public class SyncopeFormHandlerHelper extends FormHandlerHelper {
+
+ @Override
+ public TaskFormHandler getTaskFormHandlder(final String procDefId, final String taskId) {
+ Process process = ProcessDefinitionUtil.getProcess(procDefId);
+ FlowElement flowElement = process.getFlowElement(taskId, true);
+ if (flowElement instanceof UserTask) {
+ UserTask userTask = (UserTask) flowElement;
+
+ ProcessDefinition processDefinitionEntity = ProcessDefinitionUtil.getProcessDefinition(procDefId);
+ DeploymentEntity deploymentEntity = CommandContextUtil.getProcessEngineConfiguration().
+ getDeploymentEntityManager().findById(processDefinitionEntity.getDeploymentId());
+
+ TaskFormHandler taskFormHandler = new SyncopeTaskFormHandler();
+ taskFormHandler.parseConfiguration(
+ userTask.getFormProperties(), userTask.getFormKey(), deploymentEntity, processDefinitionEntity);
+ return taskFormHandler;
+ }
+
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/SyncopeTaskFormHandler.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/SyncopeTaskFormHandler.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/SyncopeTaskFormHandler.java
new file mode 100644
index 0000000..69c5e50
--- /dev/null
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/SyncopeTaskFormHandler.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.flowable.support;
+
+import java.util.List;
+import java.util.Optional;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.core.flowable.api.DropdownValueProvider;
+import org.flowable.bpmn.model.FormProperty;
+import org.flowable.common.engine.api.delegate.Expression;
+import org.flowable.common.engine.impl.el.ExpressionManager;
+import org.flowable.engine.form.AbstractFormType;
+import org.flowable.engine.impl.form.DefaultTaskFormHandler;
+import org.flowable.engine.impl.form.FormPropertyHandler;
+import org.flowable.engine.impl.form.FormTypes;
+import org.flowable.engine.impl.persistence.entity.DeploymentEntity;
+import org.flowable.engine.impl.util.CommandContextUtil;
+import org.flowable.engine.repository.ProcessDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Extends {@link DefaultTaskFormHandler} with purpose of supporting more form types than Flowable's default.
+ */
+public class SyncopeTaskFormHandler extends DefaultTaskFormHandler {
+
+ private static final long serialVersionUID = -5271243544388455797L;
+
+ protected static final Logger LOG = LoggerFactory.getLogger(SyncopeTaskFormHandler.class);
+
+ protected Optional<AbstractFormType> parseFormPropertyType(
+ final FormProperty formProperty, final ExpressionManager expressionManager) {
+
+ AbstractFormType formType = null;
+
+ switch (formProperty.getType()) {
+ case "dropdown":
+ if (formProperty.getFormValues().isEmpty()
+ || !DropdownValueProvider.NAME.equals(formProperty.getFormValues().get(0).getId())) {
+
+ LOG.warn("A single value with id '" + DropdownValueProvider.NAME + "' was expected, ignoring");
+ } else {
+ formType = new DropdownFormType(formProperty.getFormValues().get(0).getName());
+ }
+ break;
+
+ default:
+ }
+
+ return Optional.ofNullable(formType);
+ }
+
+ @Override
+ public void parseConfiguration(
+ final List<FormProperty> formProperties,
+ final String formKey,
+ final DeploymentEntity deployment,
+ final ProcessDefinition processDefinition) {
+
+ this.deploymentId = deployment.getId();
+
+ ExpressionManager expressionManager = CommandContextUtil.getProcessEngineConfiguration().getExpressionManager();
+
+ if (StringUtils.isNotEmpty(formKey)) {
+ this.formKey = expressionManager.createExpression(formKey);
+ }
+
+ FormTypes formTypes = CommandContextUtil.getProcessEngineConfiguration().getFormTypes();
+
+ formProperties.forEach(formProperty -> {
+ FormPropertyHandler formPropertyHandler = new FormPropertyHandler();
+ formPropertyHandler.setId(formProperty.getId());
+ formPropertyHandler.setName(formProperty.getName());
+
+ AbstractFormType type = parseFormPropertyType(formProperty, expressionManager).
+ orElse(formTypes.parseFormPropertyType(formProperty));
+ formPropertyHandler.setType(type);
+ formPropertyHandler.setRequired(formProperty.isRequired());
+ formPropertyHandler.setReadable(formProperty.isReadable());
+ formPropertyHandler.setWritable(formProperty.isWriteable());
+ formPropertyHandler.setVariableName(formProperty.getVariable());
+
+ if (StringUtils.isNotEmpty(formProperty.getExpression())) {
+ Expression expression = expressionManager.createExpression(formProperty.getExpression());
+ formPropertyHandler.setVariableExpression(expression);
+ }
+
+ if (StringUtils.isNotEmpty(formProperty.getDefaultExpression())) {
+ Expression defaultExpression = expressionManager.createExpression(formProperty.getDefaultExpression());
+ formPropertyHandler.setDefaultExpression(defaultExpression);
+ }
+
+ formPropertyHandlers.add(formPropertyHandler);
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/flowable-bpmn/src/main/resources/workflowFlowableContext.xml
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/resources/workflowFlowableContext.xml b/ext/flowable/flowable-bpmn/src/main/resources/workflowFlowableContext.xml
index 9e27f47..4f34237 100644
--- a/ext/flowable/flowable-bpmn/src/main/resources/workflowFlowableContext.xml
+++ b/ext/flowable/flowable-bpmn/src/main/resources/workflowFlowableContext.xml
@@ -38,6 +38,8 @@ under the License.
<property name="idmEngineConfiguration" ref="syncopeIdmEngineConfiguration"/>
</bean>
+ <bean id="syncopeFormHandlerHelper" class="org.apache.syncope.core.flowable.support.SyncopeFormHandlerHelper"/>
+
<bean class="org.apache.syncope.core.flowable.support.DomainProcessEngineConfiguration" scope="prototype">
<property name="databaseSchemaUpdate" value="true"/>
@@ -52,6 +54,8 @@ under the License.
<bean class="org.apache.syncope.core.flowable.support.SyncopeEntitiesVariableType"/>
</list>
</property>
+
+ <property name="formHandlerHelper" ref="syncopeFormHandlerHelper"/>
</bean>
<bean id="bpmnProcessManager" class="org.apache.syncope.core.flowable.impl.FlowableBpmnProcessManager"/>
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/BpmnProcessLogic.java
----------------------------------------------------------------------
diff --git a/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/BpmnProcessLogic.java b/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/BpmnProcessLogic.java
index 8d280ac..ad76605 100644
--- a/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/BpmnProcessLogic.java
+++ b/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/BpmnProcessLogic.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.logic;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.List;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.common.lib.types.FlowableEntitlement;
import org.apache.syncope.common.lib.types.BpmnProcessFormat;
import org.springframework.beans.factory.annotation.Autowired;
@@ -31,14 +31,14 @@ import org.springframework.transaction.annotation.Transactional;
import org.apache.syncope.core.flowable.api.BpmnProcessManager;
@Component
-public class BpmnProcessLogic extends AbstractTransactionalLogic<BpmnProcessTO> {
+public class BpmnProcessLogic extends AbstractTransactionalLogic<BpmnProcess> {
@Autowired
private BpmnProcessManager bpmnProcessManager;
@PreAuthorize("hasRole('" + FlowableEntitlement.BPMN_PROCESS_LIST + "')")
@Transactional(readOnly = true)
- public List<BpmnProcessTO> list() {
+ public List<BpmnProcess> list() {
return bpmnProcessManager.getProcesses();
}
@@ -65,7 +65,7 @@ public class BpmnProcessLogic extends AbstractTransactionalLogic<BpmnProcessTO>
}
@Override
- protected BpmnProcessTO resolveReference(final Method method, final Object... args)
+ protected BpmnProcess resolveReference(final Method method, final Object... args)
throws UnresolvedReferenceException {
throw new UnresolvedReferenceException();
[3/6] syncope git commit: [SYNCOPE-1369] User requests forms now
support dropdowns - via Flowable customization
Posted by il...@apache.org.
[SYNCOPE-1369] User requests forms now support dropdowns - via Flowable customization
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/6f6d9156
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/6f6d9156
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/6f6d9156
Branch: refs/heads/2_1_X
Commit: 6f6d91569d94112023f74b42898354d190d7d180
Parents: 35d46cf
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Oct 2 14:31:40 2018 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue Oct 2 14:31:40 2018 +0200
----------------------------------------------------------------------
.../console/commons/MapChoiceRenderer.java | 21 +-
.../html/form/AjaxDropDownChoicePanel.java | 3 +-
.../console/wizards/any/Relationships.java | 5 +-
.../wizards/any/Relationships.properties | 3 +
.../wizards/any/Relationships_it.properties | 3 +
.../wizards/any/Relationships_ja.properties | 3 +
.../wizards/any/Relationships_pt_BR.properties | 3 +
.../wizards/any/Relationships_ru.properties | 3 +
.../syncope/common/lib/to/RelationshipTO.java | 16 +
.../core/persistence/api/dao/AnyObjectDAO.java | 2 +-
.../persistence/jpa/dao/JPAAnyObjectDAO.java | 12 +-
.../test/resources/domains/MasterContent.xml | 6 +-
.../provisioning/java/MappingManagerImpl.java | 47 +--
.../java/data/AbstractAnyDataBinder.java | 5 +-
.../java/data/AnyObjectDataBinderImpl.java | 11 +-
.../java/data/UserDataBinderImpl.java | 7 +-
ext/flowable/client-console/pom.xml | 32 +-
.../client/console/approvals/Approval.java | 29 +-
.../approvals/ApprovalDirectoryPanel.java | 19 +-
.../syncope/client/console/pages/Flowable.java | 4 +-
.../panels/BpmnProcessDirectoryPanel.java | 48 +--
.../resources/AbstractBpmnProcessResource.java | 6 +-
.../resources/BpmnProcessGETResource.java | 4 +-
.../resources/BpmnProcessPUTResource.java | 4 +-
.../console/rest/BpmnProcessRestClient.java | 4 +-
.../console/rest/UserRequestRestClient.java | 11 +-
.../client/console/widgets/ApprovalsWidget.java | 10 +-
.../src/main/resources/dropdown.diff | 139 ++++++++
.../client/console/pages/Approvals.properties | 2 +-
.../console/pages/Approvals_it.properties | 2 +-
.../console/pages/Approvals_ja.properties | 2 +-
.../console/pages/Approvals_pt_BR.properties | 2 +-
.../console/pages/Approvals_ru.properties | 2 +-
.../syncope/common/lib/to/BpmnProcess.java | 72 ++++
.../syncope/common/lib/to/BpmnProcessTO.java | 72 ----
.../syncope/common/lib/to/UserRequest.java | 70 ++++
.../syncope/common/lib/to/UserRequestForm.java | 26 +-
.../common/lib/to/UserRequestFormProperty.java | 8 +
.../syncope/common/lib/to/UserRequestTO.java | 70 ----
.../common/lib/types/FlowableEntitlement.java | 14 +-
.../lib/types/UserRequestFormPropertyType.java | 3 +-
.../core/flowable/api/BpmnProcessManager.java | 4 +-
.../flowable/api/DropdownValueProvider.java | 31 ++
.../core/flowable/api/UserRequestHandler.java | 30 +-
.../impl/FlowableBpmnProcessManager.java | 9 +-
.../flowable/impl/FlowableRuntimeUtils.java | 50 +--
.../impl/FlowableUserRequestHandler.java | 345 ++++++++++++-------
.../support/DomainProcessEngineFactoryBean.java | 6 +
.../support/DropdownAwareJsonConverter.java | 31 ++
.../DropdownAwareUserTaskJsonConverter.java | 98 ++++++
.../core/flowable/support/DropdownFormType.java | 59 ++++
.../support/SyncopeFormHandlerHelper.java | 56 +++
.../support/SyncopeTaskFormHandler.java | 112 ++++++
.../main/resources/workflowFlowableContext.xml | 4 +
.../syncope/core/logic/BpmnProcessLogic.java | 8 +-
.../syncope/core/logic/UserRequestLogic.java | 115 +++++--
.../rest/api/beans/UserRequestFormQuery.java | 18 +
.../common/rest/api/beans/UserRequestQuery.java | 50 +++
.../rest/api/service/BpmnProcessService.java | 20 +-
.../rest/api/service/UserRequestService.java | 73 ++--
.../api/service/UserWorkflowTaskService.java | 14 +
.../cxf/service/BpmnProcessServiceImpl.java | 4 +-
.../cxf/service/UserRequestServiceImpl.java | 38 +-
fit/core-reference/pom.xml | 20 ++
.../reference/flowable/AssignDirectorGroup.java | 65 ++++
.../reference/flowable/CreateARelationship.java | 71 ++++
.../flowable/PrintersValueProvider.java | 70 ++++
.../fit/core/reference/AssignDirectorGroup.java | 63 ----
.../main/resources/all/workflowTestContext.xml | 7 +-
.../resources/assignPrinterRequest.bpmn20.xml | 92 +++++
.../syncope/fit/core/AuthenticationITCase.java | 4 +-
.../syncope/fit/core/BpmnProcessITCase.java | 4 +-
.../syncope/fit/core/UserRequestITCase.java | 135 +++++++-
.../apache/syncope/fit/core/UserSelfITCase.java | 45 +--
pom.xml | 10 +-
75 files changed, 1909 insertions(+), 657 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/client/console/src/main/java/org/apache/syncope/client/console/commons/MapChoiceRenderer.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/MapChoiceRenderer.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/MapChoiceRenderer.java
index 2845105..92d060d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/MapChoiceRenderer.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/MapChoiceRenderer.java
@@ -23,33 +23,28 @@ import java.util.Map;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.model.IModel;
-public class MapChoiceRenderer<T, K> implements IChoiceRenderer<T> {
+public class MapChoiceRenderer implements IChoiceRenderer<String> {
private static final long serialVersionUID = -7452881117778186644L;
- private final Map<T, K> map;
+ private final Map<String, String> map;
- public MapChoiceRenderer(final Map<T, K> map) {
+ public MapChoiceRenderer(final Map<String, String> map) {
this.map = map;
}
@Override
- public Object getDisplayValue(final T key) {
+ public Object getDisplayValue(final String key) {
return map.get(key);
}
@Override
- public String getIdValue(final T key, final int index) {
- return key.toString();
+ public String getIdValue(final String key, final int index) {
+ return key;
}
@Override
- public T getObject(final String id, final IModel<? extends List<? extends T>> choices) {
- for (Map.Entry<T, K> entry : map.entrySet()) {
- if (entry.getValue() != null && entry.getValue().toString().equals(id)) {
- return entry.getKey();
- }
- }
- return null;
+ public String getObject(final String id, final IModel<? extends List<? extends String>> choices) {
+ return id;
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.java
index 193c0ad..c52efac 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AjaxDropDownChoicePanel.java
@@ -44,8 +44,7 @@ public class AjaxDropDownChoicePanel<T extends Serializable> extends FieldPanel<
super(id, name, model);
- field = new BootstrapSelect<>(
- "dropDownChoiceField", model, Collections.<T>emptyList(), new ChoiceRenderer<>());
+ field = new BootstrapSelect<>("dropDownChoiceField", model, Collections.<T>emptyList(), new ChoiceRenderer<>());
add(field.setLabel(new Model<>(name)).setOutputMarkupId(true));
if (enableOnBlur) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
index 06e126b..bfbdc1d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
@@ -136,14 +136,13 @@ public class Relationships extends WizardStep implements ICondition {
public Panel getPanel(final String panelId) {
return new ListViewPanel.Builder<>(RelationshipTO.class, pageRef).
setItems(relationships.get(relationship)).
- includes("otherEndType", "otherEndKey").
+ includes("otherEndType", "otherEndKey", "otherEndName").
addAction(new ActionLink<RelationshipTO>() {
private static final long serialVersionUID = -6847033126124401556L;
@Override
- public void onClick(
- final AjaxRequestTarget target, final RelationshipTO modelObject) {
+ public void onClick(final AjaxRequestTarget target, final RelationshipTO modelObject) {
removeRelationships(relationships, modelObject);
send(Relationships.this, Broadcast.DEPTH, new ListViewReload<>(target));
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships.properties
index cfefe54..45e8a78 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships.properties
@@ -16,3 +16,6 @@
# under the License.
relationships.empty.list=No relationships defined
any.relationships=Relationships
+otherEndType=AnyType
+otherEndKey=Key
+otherEndName=Name
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_it.properties
index 5260a62..cdc900f 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_it.properties
@@ -16,3 +16,6 @@
# under the License.
relationships.empty.list=Nessuna relazione specificata
any.relationships=Relazioni
+otherEndType=AnyType
+otherEndKey=Chiave
+otherEndName=Nome
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ja.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ja.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ja.properties
index c0f26ae..5561099 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ja.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ja.properties
@@ -16,3 +16,6 @@
# under the License.
relationships.empty.list=\u95a2\u4fc2\u306f\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u307e\u305b\u3093
any.relationships=\u95a2\u4fc2
+otherEndType=AnyType
+otherEndKey=Key
+otherEndName=Name
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_pt_BR.properties
index 44f4ac8..c0c71dc 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_pt_BR.properties
@@ -16,3 +16,6 @@
# under the License.
relationships.empty.list=N\u00e3o h\u00e1 relacionamentos definidos
any.relationships=Relationships
+otherEndType=AnyType
+otherEndKey=Key
+otherEndName=Name
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ru.properties
index 93a15fb..9fcb63a 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ru.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/any/Relationships_ru.properties
@@ -17,3 +17,6 @@
relationships.empty.list=\u0421\u0432\u044f\u0437\u0438 \u043d\u0435 \u0437\u0430\u0434\u0430\u043d\u044b
any.relationships=\u0421\u0432\u044f\u0437\u0438
+otherEndType=AnyType
+otherEndKey=Key
+otherEndName=Name
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTO.java
index 015e18c..06dbd0d 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTO.java
@@ -43,6 +43,13 @@ public class RelationshipTO extends AbstractBaseBean {
return this;
}
+ public Builder otherEnd(final String otherEndType, final String otherEndKey, final String otherEndName) {
+ instance.setOtherEndType(otherEndType);
+ instance.setOtherEndKey(otherEndKey);
+ instance.setOtherEndName(otherEndName);
+ return this;
+ }
+
public RelationshipTO build() {
return instance;
}
@@ -54,6 +61,8 @@ public class RelationshipTO extends AbstractBaseBean {
private String otherEndKey;
+ private String otherEndName;
+
public String getType() {
return type;
}
@@ -78,4 +87,11 @@ public class RelationshipTO extends AbstractBaseBean {
this.otherEndKey = otherEndKey;
}
+ public String getOtherEndName() {
+ return otherEndName;
+ }
+
+ public void setOtherEndName(final String otherEndName) {
+ this.otherEndName = otherEndName;
+ }
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
index f001204..f8f05f9 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
@@ -46,7 +46,7 @@ public interface AnyObjectDAO extends AnyDAO<AnyObject> {
List<Group> findDynGroups(String key);
- List<Relationship<Any<?>, Any<?>>> findAllRelationships(AnyObject anyObject);
+ List<Relationship<Any<?>, AnyObject>> findAllRelationships(AnyObject anyObject);
Collection<Group> findAllGroups(AnyObject anyObject);
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index 4d8aaea..a7211de 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -168,20 +168,20 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
}
@Override
- public List<Relationship<Any<?>, Any<?>>> findAllRelationships(final AnyObject anyObject) {
- List<Relationship<Any<?>, Any<?>>> result = new ArrayList<>();
+ public List<Relationship<Any<?>, AnyObject>> findAllRelationships(final AnyObject anyObject) {
+ List<Relationship<Any<?>, AnyObject>> result = new ArrayList<>();
@SuppressWarnings("unchecked")
- TypedQuery<Relationship<Any<?>, Any<?>>> aquery =
- (TypedQuery<Relationship<Any<?>, Any<?>>>) entityManager().createQuery(
+ TypedQuery<Relationship<Any<?>, AnyObject>> aquery =
+ (TypedQuery<Relationship<Any<?>, AnyObject>>) entityManager().createQuery(
"SELECT e FROM " + JPAARelationship.class.getSimpleName()
+ " e WHERE e.rightEnd=:anyObject OR e.leftEnd=:anyObject");
aquery.setParameter("anyObject", anyObject);
result.addAll(aquery.getResultList());
@SuppressWarnings("unchecked")
- TypedQuery<Relationship<Any<?>, Any<?>>> uquery =
- (TypedQuery<Relationship<Any<?>, Any<?>>>) entityManager().createQuery(
+ TypedQuery<Relationship<Any<?>, AnyObject>> uquery =
+ (TypedQuery<Relationship<Any<?>, AnyObject>>) entityManager().createQuery(
"SELECT e FROM " + JPAURelationship.class.getSimpleName()
+ " e WHERE e.rightEnd=:anyObject");
uquery.setParameter("anyObject", anyObject);
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index fb05d94..5a41085 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -253,14 +253,14 @@ under the License.
<SyncopeRole_entitlements entitlement="ANYTYPE_READ" role_id="User manager"/>
<SyncopeRole_entitlements entitlement="ANYTYPECLASS_LIST" role_id="User manager"/>
<SyncopeRole_entitlements entitlement="ANYTYPECLASS_READ" role_id="User manager"/>
- <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_CLAIM" role_id="User manager"/>
- <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_SUBMIT" role_id="User manager"/>
+ <SyncopeRole_entitlements entitlement="USER_REQUEST_FORM_CLAIM" role_id="User manager"/>
+ <SyncopeRole_entitlements entitlement="USER_REQUEST_FORM_SUBMIT" role_id="User manager"/>
<SyncopeRole_Realm role_id="User manager" realm_id="e4c28e7a-9dbf-4ee7-9441-93812a0d4a28"/>
<SyncopeRole id="Other"/>
<SyncopeRole_entitlements entitlement="SCHEMA_READ" role_id="Other"/>
<SyncopeRole_entitlements entitlement="GROUP_READ" role_id="Other"/>
- <SyncopeRole_entitlements entitlement="WORKFLOW_FORM_CLAIM" role_id="Other"/>
+ <SyncopeRole_entitlements entitlement="USER_REQUEST_FORM_CLAIM" role_id="Other"/>
<SyncopeRole_Realm role_id="Other" realm_id="722f3d84-9c2b-4525-8f6e-e4b82c55a36c"/>
<SyncopeRole_Privilege role_id="Other" privilege_id="postMighty"/>
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
index b6c63e3..33077fe 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/MappingManagerImpl.java
@@ -770,11 +770,14 @@ public class MappingManagerImpl implements MappingManager {
default:
}
} else if (intAttrName.getSchemaType() != null && attr != null) {
- GroupableRelatableTO groupableTO = null;
- Group group = null;
+ GroupableRelatableTO groupableTO;
+ Group group;
if (anyTO instanceof GroupableRelatableTO && intAttrName.getMembershipOfGroup() != null) {
groupableTO = (GroupableRelatableTO) anyTO;
group = groupDAO.findByName(intAttrName.getMembershipOfGroup());
+ } else {
+ groupableTO = null;
+ group = null;
}
switch (intAttrName.getSchemaType()) {
@@ -798,29 +801,28 @@ public class MappingManagerImpl implements MappingManager {
if (groupableTO == null || group == null) {
anyTO.getPlainAttrs().add(attrTO);
} else {
- Optional<MembershipTO> membership = groupableTO.getMembership(group.getKey());
- if (!membership.isPresent()) {
- membership = Optional.of(
- new MembershipTO.Builder().group(group.getKey(), group.getName()).build());
- groupableTO.getMemberships().add(membership.get());
- }
- membership.get().getPlainAttrs().add(attrTO);
+ MembershipTO membership = groupableTO.getMembership(group.getKey()).orElseGet(() -> {
+ MembershipTO newMemb = new MembershipTO.Builder().group(group.getKey()).build();
+ groupableTO.getMemberships().add(newMemb);
+ return newMemb;
+ });
+ membership.getPlainAttrs().add(attrTO);
}
break;
case DERIVED:
attrTO = new AttrTO();
attrTO.setSchema(intAttrName.getSchemaName());
+
if (groupableTO == null || group == null) {
anyTO.getDerAttrs().add(attrTO);
} else {
- Optional<MembershipTO> membership = groupableTO.getMembership(group.getKey());
- if (!membership.isPresent()) {
- membership = Optional.of(
- new MembershipTO.Builder().group(group.getKey(), group.getName()).build());
- groupableTO.getMemberships().add(membership.get());
- }
- membership.get().getDerAttrs().add(attrTO);
+ MembershipTO membership = groupableTO.getMembership(group.getKey()).orElseGet(() -> {
+ MembershipTO newMemb = new MembershipTO.Builder().group(group.getKey()).build();
+ groupableTO.getMemberships().add(newMemb);
+ return newMemb;
+ });
+ membership.getDerAttrs().add(attrTO);
}
break;
@@ -838,13 +840,12 @@ public class MappingManagerImpl implements MappingManager {
if (groupableTO == null || group == null) {
anyTO.getVirAttrs().add(attrTO);
} else {
- Optional<MembershipTO> membership = groupableTO.getMembership(group.getKey());
- if (!membership.isPresent()) {
- membership = Optional.of(
- new MembershipTO.Builder().group(group.getKey(), group.getName()).build());
- groupableTO.getMemberships().add(membership.get());
- }
- membership.get().getVirAttrs().add(attrTO);
+ MembershipTO membership = groupableTO.getMembership(group.getKey()).orElseGet(() -> {
+ MembershipTO newMemb = new MembershipTO.Builder().group(group.getKey()).build();
+ groupableTO.getMemberships().add(newMemb);
+ return newMemb;
+ });
+ membership.getVirAttrs().add(attrTO);
}
break;
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
index 5c134df..c7499a8 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
@@ -69,6 +69,7 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
@@ -571,9 +572,9 @@ abstract class AbstractAnyDataBinder {
anyTO.getResources().addAll(resources.stream().map(Entity::getKey).collect(Collectors.toSet()));
}
- protected RelationshipTO getRelationshipTO(final String relationshipType, final Any<?> otherEnd) {
+ protected RelationshipTO getRelationshipTO(final String relationshipType, final AnyObject otherEnd) {
return new RelationshipTO.Builder().
- type(relationshipType).otherEnd(otherEnd.getType().getKey(), otherEnd.getKey()).
+ type(relationshipType).otherEnd(otherEnd.getType().getKey(), otherEnd.getKey(), otherEnd.getName()).
build();
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
index 129d0e4..1dd6194 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
@@ -101,11 +101,12 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
// relationships
anyObjectTO.getRelationships().addAll(
- anyObjectDAO.findAllRelationships(anyObject).stream().map(relationship -> getRelationshipTO(
- relationship.getType().getKey(),
- relationship.getLeftEnd().getKey().equals(anyObject.getKey())
- ? relationship.getRightEnd()
- : relationship.getLeftEnd())).
+ anyObjectDAO.findAllRelationships(anyObject).stream().
+ map(relationship -> getRelationshipTO(
+ relationship.getType().getKey(),
+ relationship.getLeftEnd().getKey().equals(anyObject.getKey())
+ ? relationship.getRightEnd()
+ : anyObject)).
collect(Collectors.toList()));
// memberships
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
index d328c43..58c2d7d 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
@@ -602,10 +602,9 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
flatMap(role -> role.getPrivileges().stream()).map(Entity::getKey).collect(Collectors.toSet()));
// relationships
- userTO.getRelationships().addAll(
- user.getRelationships().stream().map(relationship -> getRelationshipTO(
- relationship.getType().getKey(), relationship.getRightEnd())).
- collect(Collectors.toList()));
+ userTO.getRelationships().addAll(user.getRelationships().stream().
+ map(relationship -> getRelationshipTO(relationship.getType().getKey(), relationship.getRightEnd())).
+ collect(Collectors.toList()));
// memberships
userTO.getMemberships().addAll(
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/pom.xml
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/pom.xml b/ext/flowable/client-console/pom.xml
index 6f8020f..1d609b1 100644
--- a/ext/flowable/client-console/pom.xml
+++ b/ext/flowable/client-console/pom.xml
@@ -83,35 +83,37 @@ under the License.
<target>
<unzip src="${settings.localRepository}/org/flowable/flowable-ui-modeler-app/${flowable.version}/flowable-ui-modeler-app-${flowable.version}.war" dest="${flowable-modeler.directory}">
<patternset>
- <include name="WEB-INF/classes/static/**" />
- <include name="WEB-INF/lib/flowable-ui-modeler-logic-${flowable.version}.jar" />
+ <include name="WEB-INF/classes/static/**"/>
+ <include name="WEB-INF/lib/flowable-ui-modeler-logic-${flowable.version}.jar"/>
</patternset>
</unzip>
<unzip src="${flowable-modeler.directory}/WEB-INF/lib/flowable-ui-modeler-logic-${flowable.version}.jar" dest="${flowable-modeler.directory}">
<patternset>
- <include name="stencilset_bpmn.json" />
+ <include name="stencilset_bpmn.json"/>
</patternset>
</unzip>
<move todir="${flowable-modeler.directory}">
<fileset dir="${flowable-modeler.directory}/WEB-INF/classes/static/">
- <include name="**" />
+ <include name="**"/>
</fileset>
</move>
- <delete dir="${flowable-modeler.directory}/WEB-INF" />
+ <delete dir="${flowable-modeler.directory}/WEB-INF"/>
- <replace file="${flowable-modeler.directory}/index.html" token="</head>" value="<script type="text/javascript">window.onunload = refreshParent; function refreshParent() { window.opener.location.reload(); }</script></head>" />
- <replace file="${flowable-modeler.directory}/index.html" token=" ng-click="backToLanding()"" value=" disabled="disabled"" />
- <replace file="${flowable-modeler.directory}/index.html" token="<ul class="nav navbar-nav" id="main-nav"" value="<ul class="nav navbar-nav" id="main-nav" style="display: none;"" />
- <replace file="${flowable-modeler.directory}/index.html" token="<div class="pull-right" value="<div style="display: none;" class="pull-right" />
- <replace file="${flowable-modeler.directory}/editor-app/editor.html" token="<div class="btn-group pull-right"" value="<div style="display: none;" class="btn-group pull-right"" />
- <replace file="${flowable-modeler.directory}/editor-app/configuration/toolbar-default-actions.js" token="$location.path('/processes');" value="window.close();" />
+ <replace file="${flowable-modeler.directory}/index.html" token="</head>" value="<script type="text/javascript">window.onunload = refreshParent; function refreshParent() { window.opener.location.reload(); }</script></head>"/>
+ <replace file="${flowable-modeler.directory}/index.html" token=" ng-click="backToLanding()"" value=" disabled="disabled""/>
+ <replace file="${flowable-modeler.directory}/index.html" token="<ul class="nav navbar-nav" id="main-nav"" value="<ul class="nav navbar-nav" id="main-nav" style="display: none;""/>
+ <replace file="${flowable-modeler.directory}/index.html" token="<div class="pull-right" value="<div style="display: none;" class="pull-right"/>
+ <replace file="${flowable-modeler.directory}/editor-app/editor.html" token="<div class="btn-group pull-right"" value="<div style="display: none;" class="btn-group pull-right""/>
+ <replace file="${flowable-modeler.directory}/editor-app/configuration/toolbar-default-actions.js" token="$location.path('/processes');" value="window.close();"/>
- <copy file="${basedir}/src/main/resources/app-cfg.js" todir="${flowable-modeler.directory}/scripts" overwrite="true" />
- <copy file="${basedir}/src/main/resources/url-config.js" todir="${flowable-modeler.directory}/editor-app/configuration" overwrite="true" />
- <copy file="${basedir}/src/main/resources/toolbar.js" todir="${flowable-modeler.directory}/editor-app/configuration" overwrite="true" />
- <copy file="${basedir}/src/main/resources/save-model.html" todir="${flowable-modeler.directory}/editor-app/popups" overwrite="true" />
+ <copy file="${basedir}/src/main/resources/app-cfg.js" todir="${flowable-modeler.directory}/scripts" overwrite="true"/>
+ <copy file="${basedir}/src/main/resources/url-config.js" todir="${flowable-modeler.directory}/editor-app/configuration" overwrite="true"/>
+ <copy file="${basedir}/src/main/resources/toolbar.js" todir="${flowable-modeler.directory}/editor-app/configuration" overwrite="true"/>
+ <copy file="${basedir}/src/main/resources/save-model.html" todir="${flowable-modeler.directory}/editor-app/popups" overwrite="true"/>
+
+ <patch patchfile="${basedir}/src/main/resources/dropdown.diff" dir="${flowable-modeler.directory}" strip="1"/>
</target>
</configuration>
<goals>
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/Approval.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/Approval.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/Approval.java
index 3bea1a9..6a66afc 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/Approval.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/Approval.java
@@ -45,7 +45,6 @@ import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
-import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -103,7 +102,7 @@ public abstract class Approval extends Panel {
break;
case Date:
- final FastDateFormat formatter = FastDateFormat.getInstance(prop.getDatePattern());
+ FastDateFormat formatter = FastDateFormat.getInstance(prop.getDatePattern());
field = new AjaxDateTimeFieldPanel("value", label, new PropertyModel<Date>(prop, "value") {
private static final long serialVersionUID = -3743432456095828573L;
@@ -111,11 +110,9 @@ public abstract class Approval extends Panel {
@Override
public Date getObject() {
try {
- if (StringUtils.isBlank(prop.getValue())) {
- return null;
- } else {
- return formatter.parse(prop.getValue());
- }
+ return StringUtils.isBlank(prop.getValue())
+ ? null
+ : formatter.parse(prop.getValue());
} catch (ParseException e) {
LOG.error("Unparsable date: {}", prop.getValue(), e);
return null;
@@ -131,19 +128,17 @@ public abstract class Approval extends Panel {
break;
case Enum:
- MapChoiceRenderer<String, String> enumCR = new MapChoiceRenderer<>(prop.getEnumValues());
-
field = new AjaxDropDownChoicePanel(
"value", label, new PropertyModel<String>(prop, "value"), false).
- setChoiceRenderer(enumCR).setChoices(new Model<ArrayList<String>>() {
-
- private static final long serialVersionUID = -858521070366432018L;
+ setChoiceRenderer(new MapChoiceRenderer(prop.getEnumValues())).
+ setChoices(new ArrayList<>(prop.getEnumValues().keySet()));
+ break;
- @Override
- public ArrayList<String> getObject() {
- return new ArrayList<>(prop.getEnumValues().keySet());
- }
- });
+ case Dropdown:
+ field = new AjaxDropDownChoicePanel(
+ "value", label, new PropertyModel<String>(prop, "value"), false).
+ setChoiceRenderer(new MapChoiceRenderer(prop.getDropdownValues())).
+ setChoices(new ArrayList<>(prop.getDropdownValues().keySet()));
break;
case Long:
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
index e16f5c2..577ea65 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
@@ -113,7 +113,7 @@ public class ApprovalDirectoryPanel
initResultTable();
- MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, FlowableEntitlement.WORKFLOW_FORM_SUBMIT);
+ MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, FlowableEntitlement.USER_REQUEST_FORM_SUBMIT);
}
@Override
@@ -121,7 +121,7 @@ public class ApprovalDirectoryPanel
List<IColumn<UserRequestForm, String>> columns = new ArrayList<>();
columns.add(new PropertyColumn<>(
- new ResourceModel("taskId"), "taskId", "taskId"));
+ new ResourceModel("bpmnProcess"), "bpmnProcess", "bpmnProcess"));
columns.add(new PropertyColumn<>(
new ResourceModel("key"), "formKey", "formKey"));
columns.add(new PropertyColumn<>(
@@ -151,7 +151,7 @@ public class ApprovalDirectoryPanel
((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
target.add(container);
}
- }, ActionLink.ActionType.CLAIM, FlowableEntitlement.WORKFLOW_FORM_CLAIM);
+ }, ActionLink.ActionType.CLAIM, FlowableEntitlement.USER_REQUEST_FORM_CLAIM);
panel.add(new ActionLink<UserRequestForm>() {
@@ -190,7 +190,7 @@ public class ApprovalDirectoryPanel
equals(model.getObject().getOwner());
}
- }, ActionLink.ActionType.MANAGE_APPROVAL, FlowableEntitlement.WORKFLOW_FORM_READ);
+ }, ActionLink.ActionType.MANAGE_APPROVAL, FlowableEntitlement.USER_REQUEST_FORM_SUBMIT);
// SYNCOPE-1200 edit user while in approval state
panel.add(new ActionLink<UserRequestForm>() {
@@ -239,7 +239,7 @@ public class ApprovalDirectoryPanel
equals(model.getObject().getOwner());
}
- }, ActionLink.ActionType.EDIT_APPROVAL, FlowableEntitlement.WORKFLOW_FORM_SUBMIT);
+ }, ActionLink.ActionType.EDIT_APPROVAL, FlowableEntitlement.USER_REQUEST_FORM_SUBMIT);
return panel;
}
@@ -326,8 +326,6 @@ public class ApprovalDirectoryPanel
protected Serializable onApplyInternal(final AnyWrapper<UserTO> modelObject) {
UserTO inner = modelObject.getInnerObject();
- ProvisioningResult<UserTO> result;
-
UserPatch patch = AnyOperations.diff(inner, formTO.getUserTO(), false);
if (StringUtils.isNotBlank(inner.getPassword())) {
@@ -337,16 +335,15 @@ public class ApprovalDirectoryPanel
build();
patch.setPassword(passwordPatch);
}
+
// update just if it is changed
+ ProvisioningResult<UserTO> result;
if (patch.isEmpty()) {
result = new ProvisioningResult<>();
result.setEntity(inner);
} else {
result = userRestClient.update(getOriginalItem().getInnerObject().getETagValue(), patch);
- UserRequestForm workFlowTO = restClient.getForms(result.getEntity().getKey()).get(0);
- if (workFlowTO != null) {
- claimForm(workFlowTO.getTaskId());
- }
+ restClient.getForm(result.getEntity().getKey()).ifPresent(form -> claimForm(form.getTaskId()));
}
return result;
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/pages/Flowable.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/pages/Flowable.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/pages/Flowable.java
index 562aad1..8062a77 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/pages/Flowable.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/pages/Flowable.java
@@ -23,7 +23,7 @@ import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.client.console.annotations.ExtPage;
import org.apache.syncope.client.console.panels.BpmnProcessDirectoryPanel;
import org.apache.syncope.client.console.wizards.WizardMgtPanel;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.common.lib.types.FlowableEntitlement;
import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
import org.apache.wicket.markup.html.WebMarkupContainer;
@@ -48,7 +48,7 @@ public class Flowable extends BaseExtPage {
disabled.setOutputMarkupPlaceholderTag(true);
content.add(disabled);
- WizardMgtPanel<BpmnProcessTO> bpmnProcessesPanel = new BpmnProcessDirectoryPanel.Builder(getPageReference()) {
+ WizardMgtPanel<BpmnProcess> bpmnProcessesPanel = new BpmnProcessDirectoryPanel.Builder(getPageReference()) {
private static final long serialVersionUID = -5960765294082359003L;
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java
index b7914bb..8f4d566 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/BpmnProcessDirectoryPanel.java
@@ -43,7 +43,7 @@ import org.apache.syncope.client.console.wicket.markup.html.form.XMLEditorPanel;
import org.apache.syncope.client.console.wizards.AjaxWizardBuilder;
import org.apache.syncope.client.console.wizards.WizardMgtPanel;
import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.common.lib.types.FlowableEntitlement;
import org.apache.wicket.Page;
import org.apache.wicket.PageReference;
@@ -65,7 +65,7 @@ import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.util.io.IOUtils;
public class BpmnProcessDirectoryPanel extends DirectoryPanel<
- BpmnProcessTO, BpmnProcessTO, BpmProcessDataProvider, BpmnProcessRestClient> {
+ BpmnProcess, BpmnProcess, BpmProcessDataProvider, BpmnProcessRestClient> {
private static final long serialVersionUID = 2705668831139984998L;
@@ -76,13 +76,13 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
protected BpmnProcessDirectoryPanel(final String id, final Builder builder) {
super(id, builder);
- this.addNewItemPanelBuilder(new AjaxWizardBuilder<BpmnProcessTO>(new BpmnProcessTO(), pageRef) {
+ this.addNewItemPanelBuilder(new AjaxWizardBuilder<BpmnProcess>(new BpmnProcess(), pageRef) {
private static final long serialVersionUID = 1633859795677053912L;
@Override
protected WizardModel buildModelSteps(
- final BpmnProcessTO modelObject, final WizardModel wizardModel) {
+ final BpmnProcess modelObject, final WizardModel wizardModel) {
return wizardModel;
}
@@ -133,8 +133,8 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
@Override
- protected List<IColumn<BpmnProcessTO, String>> getColumns() {
- List<IColumn<BpmnProcessTO, String>> columns = new ArrayList<>();
+ protected List<IColumn<BpmnProcess, String>> getColumns() {
+ List<IColumn<BpmnProcess, String>> columns = new ArrayList<>();
columns.add(new PropertyColumn<>(new ResourceModel("key"), "key"));
columns.add(new PropertyColumn<>(new ResourceModel("name"), "name", "name"));
@@ -143,15 +143,15 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
@Override
- public ActionsPanel<BpmnProcessTO> getActions(final IModel<BpmnProcessTO> model) {
- final ActionsPanel<BpmnProcessTO> panel = super.getActions(model);
+ public ActionsPanel<BpmnProcess> getActions(final IModel<BpmnProcess> model) {
+ final ActionsPanel<BpmnProcess> panel = super.getActions(model);
- panel.add(new ActionLink<BpmnProcessTO>() {
+ panel.add(new ActionLink<BpmnProcess>() {
private static final long serialVersionUID = -184018732772021627L;
@Override
- public void onClick(final AjaxRequestTarget target, final BpmnProcessTO ignore) {
+ public void onClick(final AjaxRequestTarget target, final BpmnProcess ignore) {
final IModel<String> wfDefinition = new Model<>();
try {
wfDefinition.setObject(IOUtils.toString(restClient.getDefinition(
@@ -189,12 +189,12 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
}, ActionLink.ActionType.EDIT, FlowableEntitlement.BPMN_PROCESS_SET);
- panel.add(new ActionLink<BpmnProcessTO>() {
+ panel.add(new ActionLink<BpmnProcess>() {
private static final long serialVersionUID = 3109256773218160485L;
@Override
- public void onClick(final AjaxRequestTarget target, final BpmnProcessTO ignore) {
+ public void onClick(final AjaxRequestTarget target, final BpmnProcess ignore) {
modal.header(Model.of(model.getObject().getKey()));
modal.setContent(new ImageModalPanel<>(
modal, restClient.getDiagram(model.getObject().getKey()), pageRef));
@@ -203,7 +203,7 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
}, ActionLink.ActionType.VIEW, FlowableEntitlement.BPMN_PROCESS_GET);
- panel.add(new ActionLink<BpmnProcessTO>() {
+ panel.add(new ActionLink<BpmnProcess>() {
private static final long serialVersionUID = -184018732772021627L;
@@ -222,22 +222,22 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
@Override
- public void onClick(final AjaxRequestTarget target, final BpmnProcessTO ignore) {
+ public void onClick(final AjaxRequestTarget target, final BpmnProcess ignore) {
// do nothing
}
}, ActionLink.ActionType.EXTERNAL_EDITOR, FlowableEntitlement.BPMN_PROCESS_SET);
- panel.add(new ActionLink<BpmnProcessTO>() {
+ panel.add(new ActionLink<BpmnProcess>() {
private static final long serialVersionUID = -7978723352517770644L;
@Override
- protected boolean statusCondition(final BpmnProcessTO modelObject) {
+ protected boolean statusCondition(final BpmnProcess modelObject) {
return !modelObject.isUserWorkflow();
}
@Override
- public void onClick(final AjaxRequestTarget target, final BpmnProcessTO ignore) {
+ public void onClick(final AjaxRequestTarget target, final BpmnProcess ignore) {
try {
restClient.deleteDefinition(model.getObject().getKey());
SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
@@ -260,7 +260,7 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
public abstract static class Builder
- extends DirectoryPanel.Builder<BpmnProcessTO, BpmnProcessTO, BpmnProcessRestClient> {
+ extends DirectoryPanel.Builder<BpmnProcess, BpmnProcess, BpmnProcessRestClient> {
private static final long serialVersionUID = 5088962796986706805L;
@@ -269,16 +269,16 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
@Override
- protected WizardMgtPanel<BpmnProcessTO> newInstance(final String id, final boolean wizardInModal) {
+ protected WizardMgtPanel<BpmnProcess> newInstance(final String id, final boolean wizardInModal) {
return new BpmnProcessDirectoryPanel(id, this);
}
}
- protected class BpmProcessDataProvider extends DirectoryDataProvider<BpmnProcessTO> {
+ protected class BpmProcessDataProvider extends DirectoryDataProvider<BpmnProcess> {
private static final long serialVersionUID = 1764153405387687592L;
- private final SortableDataProviderComparator<BpmnProcessTO> comparator;
+ private final SortableDataProviderComparator<BpmnProcess> comparator;
private final BpmnProcessRestClient restClient = new BpmnProcessRestClient();
@@ -289,8 +289,8 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
@Override
- public Iterator<BpmnProcessTO> iterator(final long first, final long count) {
- List<BpmnProcessTO> result = restClient.getDefinitions();
+ public Iterator<BpmnProcess> iterator(final long first, final long count) {
+ List<BpmnProcess> result = restClient.getDefinitions();
Collections.sort(result, comparator);
return result.subList((int) first, (int) first + (int) count).iterator();
}
@@ -301,7 +301,7 @@ public class BpmnProcessDirectoryPanel extends DirectoryPanel<
}
@Override
- public IModel<BpmnProcessTO> model(final BpmnProcessTO object) {
+ public IModel<BpmnProcess> model(final BpmnProcess object) {
return new CompoundPropertyModel<>(object);
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/AbstractBpmnProcessResource.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/AbstractBpmnProcessResource.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/AbstractBpmnProcessResource.java
index 91a42e3..7ad5f24 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/AbstractBpmnProcessResource.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/AbstractBpmnProcessResource.java
@@ -21,7 +21,7 @@ package org.apache.syncope.client.console.resources;
import javax.ws.rs.NotFoundException;
import org.apache.syncope.client.console.commons.Constants;
import org.apache.syncope.client.console.rest.BpmnProcessRestClient;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.wicket.request.resource.AbstractResource;
import org.apache.wicket.util.string.StringValue;
import org.slf4j.Logger;
@@ -35,10 +35,10 @@ abstract class AbstractBpmnProcessResource extends AbstractResource {
protected final BpmnProcessRestClient restClient = new BpmnProcessRestClient();
- protected BpmnProcessTO getBpmnProcess(final Attributes attributes) {
+ protected BpmnProcess getBpmnProcess(final Attributes attributes) {
StringValue modelId = attributes.getRequest().getQueryParameters().getParameterValue(Constants.MODEL_ID_PARAM);
- BpmnProcessTO bpmnProcess = modelId == null || modelId.isNull()
+ BpmnProcess bpmnProcess = modelId == null || modelId.isNull()
? null
: restClient.getDefinitions().stream().
filter(object -> modelId.toString().equals(object.getModelId())).findAny().orElse(null);
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessGETResource.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessGETResource.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessGETResource.java
index ba34502..dfe633e 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessGETResource.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessGETResource.java
@@ -23,7 +23,7 @@ import java.nio.charset.StandardCharsets;
import javax.ws.rs.core.MediaType;
import org.apache.syncope.client.console.annotations.Resource;
import org.apache.syncope.client.console.rest.BpmnProcessRestClient;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.wicket.util.io.IOUtils;
/**
@@ -36,7 +36,7 @@ public class BpmnProcessGETResource extends AbstractBpmnProcessResource {
@Override
protected ResourceResponse newResourceResponse(final Attributes attributes) {
- final BpmnProcessTO toGet = getBpmnProcess(attributes);
+ final BpmnProcess toGet = getBpmnProcess(attributes);
ResourceResponse response = new ResourceResponse();
response.disableCaching();
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessPUTResource.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessPUTResource.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessPUTResource.java
index d583396..1031ce8 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessPUTResource.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/resources/BpmnProcessPUTResource.java
@@ -24,7 +24,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.cxf.common.util.UrlUtils;
import org.apache.syncope.client.console.annotations.Resource;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.wicket.util.io.IOUtils;
/**
@@ -52,7 +52,7 @@ public class BpmnProcessPUTResource extends AbstractBpmnProcessResource {
LOG.error("Could not extract BPMN process", e);
}
- BpmnProcessTO toSet = getBpmnProcess(attributes);
+ BpmnProcess toSet = getBpmnProcess(attributes);
if (definition == null || toSet == null) {
return new ResourceResponse().setStatusCode(Response.Status.BAD_REQUEST.getStatusCode()).
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/BpmnProcessRestClient.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/BpmnProcessRestClient.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/BpmnProcessRestClient.java
index 2b7c368..9e88431 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/BpmnProcessRestClient.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/BpmnProcessRestClient.java
@@ -25,7 +25,7 @@ import javax.ws.rs.core.Response;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.common.rest.api.RESTHeaders;
import org.apache.syncope.common.rest.api.service.BpmnProcessService;
@@ -37,7 +37,7 @@ public class BpmnProcessRestClient extends BaseRestClient {
return SyncopeConsoleSession.get().getService(mediaType, BpmnProcessService.class);
}
- public List<BpmnProcessTO> getDefinitions() {
+ public List<BpmnProcess> getDefinitions() {
return getService(BpmnProcessService.class).list();
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/UserRequestRestClient.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/UserRequestRestClient.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/UserRequestRestClient.java
index 555555b..e3a179f 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/UserRequestRestClient.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/rest/UserRequestRestClient.java
@@ -19,6 +19,8 @@
package org.apache.syncope.client.console.rest;
import java.util.List;
+import java.util.Optional;
+import org.apache.syncope.common.lib.to.PagedResult;
import org.apache.syncope.common.lib.to.UserRequestForm;
import org.apache.syncope.common.rest.api.beans.UserRequestFormQuery;
import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
@@ -40,8 +42,13 @@ public class UserRequestRestClient extends BaseRestClient {
getResult();
}
- public List<UserRequestForm> getForms(final String userKey) {
- return getService(UserRequestService.class).getForms(userKey);
+ public Optional<UserRequestForm> getForm(final String userKey) {
+ PagedResult<UserRequestForm> forms = getService(UserRequestService.class).
+ getForms(new UserRequestFormQuery.Builder().user(userKey).page(1).size(1).build());
+ UserRequestForm form = forms.getResult().isEmpty()
+ ? null
+ : forms.getResult().get(0);
+ return Optional.ofNullable(form);
}
public UserRequestForm claimForm(final String taskKey) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/widgets/ApprovalsWidget.java
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/widgets/ApprovalsWidget.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/widgets/ApprovalsWidget.java
index 8f8329e..9a9fd2d 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/widgets/ApprovalsWidget.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/widgets/ApprovalsWidget.java
@@ -87,8 +87,7 @@ public class ApprovalsWidget extends ExtAlertWidget<UserRequestForm> {
@Override
protected int getLatestAlertsSize() {
- return SyncopeConsoleSession.get().owns(FlowableEntitlement.WORKFLOW_FORM_LIST)
- && SyncopeConsoleSession.get().owns(FlowableEntitlement.WORKFLOW_FORM_READ)
+ return SyncopeConsoleSession.get().owns(FlowableEntitlement.USER_REQUEST_FORM_LIST)
? restClient.countForms()
: 0;
}
@@ -102,9 +101,7 @@ public class ApprovalsWidget extends ExtAlertWidget<UserRequestForm> {
@Override
public List<UserRequestForm> getObject() {
List<UserRequestForm> updatedApprovals;
- if (SyncopeConsoleSession.get().owns(FlowableEntitlement.WORKFLOW_FORM_LIST)
- && SyncopeConsoleSession.get().owns(FlowableEntitlement.WORKFLOW_FORM_READ)) {
-
+ if (SyncopeConsoleSession.get().owns(FlowableEntitlement.USER_REQUEST_FORM_LIST)) {
updatedApprovals = restClient.getForms(1, MAX_SIZE, new SortParam<>("createTime", true));
} else {
updatedApprovals = Collections.<UserRequestForm>emptyList();
@@ -118,7 +115,8 @@ public class ApprovalsWidget extends ExtAlertWidget<UserRequestForm> {
@Override
protected AbstractLink getEventsLink(final String linkid) {
BookmarkablePageLink<Approvals> approvals = BookmarkablePageLinkBuilder.build(linkid, Approvals.class);
- MetaDataRoleAuthorizationStrategy.authorize(approvals, WebPage.ENABLE, FlowableEntitlement.WORKFLOW_FORM_LIST);
+ MetaDataRoleAuthorizationStrategy.authorize(
+ approvals, WebPage.ENABLE, FlowableEntitlement.USER_REQUEST_FORM_LIST);
return approvals;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/src/main/resources/dropdown.diff
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/resources/dropdown.diff b/ext/flowable/client-console/src/main/resources/dropdown.diff
new file mode 100644
index 0000000..80fe1e7
--- /dev/null
+++ b/ext/flowable/client-console/src/main/resources/dropdown.diff
@@ -0,0 +1,139 @@
+# 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.
+diff --git a/editor-app/configuration/properties-form-properties-controller.js b/editor-app/configuration/properties-form-properties-controller.js
+index ca8f051..fc02151 100644
+--- a/editor-app/configuration/properties-form-properties-controller.js
++++ b/editor-app/configuration/properties-form-properties-controller.js
+@@ -102,6 +102,20 @@ angular.module('flowableModeler').controller('FlowableFormPropertiesPopupCtrl',
+ { field: 'name', displayName: $scope.labels.nameLabel}]
+ }
+
++ $scope.dropdownGridOptions = {
++ data: $scope.enumValues,
++ headerRowHeight: 28,
++ enableRowSelection: true,
++ enableRowHeaderSelection: false,
++ multiSelect: false,
++ modifierKeysToMultiSelect: false,
++ enableHorizontalScrollbar: 0,
++ enableColumnMenus: false,
++ enableSorting: false,
++ columnDefs: [{ field: 'id', displayName: $scope.labels.idLabel },
++ { field: 'name', displayName: $scope.labels.nameLabel}]
++ }
++
+ $scope.gridOptions.onRegisterApi = function (gridApi) {
+ //set gridApi on scope
+ $scope.gridApi = gridApi;
+@@ -124,6 +138,13 @@ angular.module('flowableModeler').controller('FlowableFormPropertiesPopupCtrl',
+ $scope.selectedEnumValue = row.entity;
+ });
+ };
++ $scope.dropdownGridOptions.onRegisterApi = function (gridApi) {
++ //set gridApi on scope
++ $scope.dropdownGridApi = gridApi;
++ gridApi.selection.on.rowSelectionChanged($scope, function (row) {
++ $scope.selectedDropdownValue = row.entity;
++ });
++ };
+ });
+
+ // Handler for when the value of the type dropdown changes
+@@ -143,7 +164,12 @@ angular.module('flowableModeler').controller('FlowableFormPropertiesPopupCtrl',
+ for (var i = 0; i < $scope.selectedProperty.enumValues.length; i++) {
+ $scope.enumValues.push($scope.selectedProperty.enumValues[i]);
+ }
+-
++ } else if ($scope.selectedProperty.type === 'dropdown') {
++ $scope.selectedProperty.enumValues = [ {id: 'dropdownValueProvider', name: 'provider'}];
++ $scope.enumValues.length = 0;
++ for (var i = 0; i < $scope.selectedProperty.enumValues.length; i++) {
++ $scope.enumValues.push($scope.selectedProperty.enumValues[i]);
++ }
+ } else {
+ delete $scope.selectedProperty.enumValues;
+ $scope.enumValues.length = 0;
+@@ -324,4 +350,4 @@ angular.module('flowableModeler').controller('FlowableFormPropertiesPopupCtrl',
+ };
+
+ }])
+-;
+\ No newline at end of file
++;
+diff --git a/editor-app/configuration/properties/form-properties-popup.html b/editor-app/configuration/properties/form-properties-popup.html
+index 17c5ca8..57a24e5 100644
+--- a/editor-app/configuration/properties/form-properties-popup.html
++++ b/editor-app/configuration/properties/form-properties-popup.html
+@@ -42,6 +42,7 @@
+ <option>boolean</option>
+ <option>date</option>
+ <option>enum</option>
++ <option>dropdown</option>
+ </select>
+ </div>
+ <div class="form-group" ng-show="selectedProperty.datePattern">
+@@ -80,6 +81,38 @@
+ </div>
+ </div>
+ </div>
++ <div ng-show="selectedProperty.type == 'dropdown'" style="padding-bottom:10px">
++ <div class="row row-no-gutter">
++ <div class="col-xs-6">
++ <div ng-if="translationsRetrieved" class="kis-listener-grid" ui-grid="dropdownGridOptions" ui-grid-selection ui-grid-auto-resize></div>
++ <!--<div class="pull-right">
++ <div class="btn-group">
++ <a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.MOVE.UP | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="moveEnumValueUp()"><i class="glyphicon glyphicon-arrow-up"></i></a>
++ <a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.MOVE.DOWN | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="moveEnumValueDown()"><i class="glyphicon glyphicon-arrow-down"></i></a>
++ </div>
++ <div class="btn-group">
++ <a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.ADD | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="addNewEnumValue()"><i class="glyphicon glyphicon-plus"></i></a>
++ <a class="btn btn-icon btn-lg" rel="tooltip" data-title="{{ACTION.REMOVE | translate}}" data-placement="bottom" data-original-title="" title="" ng-click="removeEnumValue()"><i class="glyphicon glyphicon-minus"></i></a>
++ </div>
++ </div>-->
++ </div>
++
++ <div class="col-xs-6">
++ <div ng-show="selectedDropdownValue">
++
++ <div class="form-group">
++ <label for="classField">{{'PROPERTY.FORMPROPERTIES.VALUES.ID' | translate}}</label>
++ <input type="text" id="classField" class="form-control" ng-model="selectedDropdownValue.id" placeholder="{{'PROPERTY.FORMPROPERTIES.VALUES.ID.PLACEHOLDER' | translate}}" />
++ </div>
++ <div class="form-group">
++ <label for="classField">{{'PROPERTY.FORMPROPERTIES.VALUES.NAME' | translate}}</label>
++ <input type="text" id="classField" class="form-control" ng-model="selectedDropdownValue.name" placeholder="{{'PROPERTY.FORMPROPERTIES.VALUES.NAME.PLACEHOLDER' | translate}}" />
++ </div>
++ </div>
++ <div ng-show="!selectedDropdownValue" class="muted no-property-selected" translate>PROPERTY.FORMPROPERTIES.DROPDOWNVALUES.EMPTY</div>
++ </div>
++ </div>
++ </div>
+ <div class="form-group">
+ <label for="expressionField">{{'PROPERTY.FORMPROPERTIES.EXPRESSION' | translate}}</label>
+ <input id="expressionField" class="form-control" type="text" ng-model="selectedProperty.expression" placeholder="{{'PROPERTY.FORMPROPERTIES.EXPRESSION.PLACEHOLDER' | translate }}" />
+diff --git a/i18n/en.json b/i18n/en.json
+index 7d0e40a..1067dad 100644
+--- a/i18n/en.json
++++ b/i18n/en.json
+@@ -824,6 +824,7 @@
+ "PROPERTY.FORMPROPERTIES.DATEPATTERN.PLACEHOLDER" : "Enter date pattern",
+ "PROPERTY.FORMPROPERTIES.VALUES" : "Values",
+ "PROPERTY.FORMPROPERTIES.ENUMVALUES.EMPTY" : "No enum value selected",
++ "PROPERTY.FORMPROPERTIES.DROPDOWNVALUES.EMPTY" : "No dropdown value selected",
+ "PROPERTY.FORMPROPERTIES.VALUES.ID" : "Id",
+ "PROPERTY.FORMPROPERTIES.VALUES.NAME" : "Name",
+ "PROPERTY.FORMPROPERTIES.VALUES.ID.PLACEHOLDER" : "Enter id of a value",
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals.properties
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals.properties b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals.properties
index 1ea8063..84b9c85 100644
--- a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals.properties
+++ b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals.properties
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-taskId=Task
+bpmnProcess=User Request
key=Key
description=Description
createTime=Create Time
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_it.properties
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_it.properties b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_it.properties
index 7e12ce5..f25abd8 100644
--- a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_it.properties
+++ b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_it.properties
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-taskId=Task
+bpmnProcess=User Request
key=Chiave
description=Descrizione
createTime=Data di creazione
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ja.properties
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ja.properties b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ja.properties
index b2ff626..dcca6e1 100644
--- a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ja.properties
+++ b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ja.properties
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-taskId=\u30bf\u30b9\u30af
+bpmnProcess=User Request
key=\u30ad\u30fc
description=\u8aac\u660e
createTime=\u4f5c\u6210\u6642\u523b
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_pt_BR.properties
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_pt_BR.properties b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_pt_BR.properties
index e5ff74c..88a9e05 100644
--- a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_pt_BR.properties
+++ b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_pt_BR.properties
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-taskId=Tarefa
+bpmnProcess=User Request
key=Chave
description=Descri\u00e7\u00e3o
createTime=Tempo de Cria\u00e7\u00e3o
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ru.properties
----------------------------------------------------------------------
diff --git a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ru.properties b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ru.properties
index 6f4fb58..2e7a199 100644
--- a/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ru.properties
+++ b/ext/flowable/client-console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ru.properties
@@ -16,7 +16,7 @@
# under the License.
#
# taskId=\u00d0\u0097\u00d0\u00b0\u00d1\u008f\u00d0\u00b2\u00d0\u00ba\u00d0\u00b0
-taskId=\u0417\u0430\u044f\u0432\u043a\u0430
+bpmnProcess=User Request
# key=\u00d0\u0098\u00d0\u00b4\u00d0\u00b5\u00d0\u00bd\u00d1\u0082\u00d0\u00b8\u00d1\u0084\u00d0\u00b8\u00d0\u00ba\u00d0\u00b0\u00d1\u0082\u00d0\u00be\u00d1\u0080
key=\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440
# description=\u00d0\u009e\u00d0\u00bf\u00d0\u00b8\u00d1\u0081\u00d0\u00b0\u00d0\u00bd\u00d0\u00b8\u00d0\u00b5
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcess.java
----------------------------------------------------------------------
diff --git a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcess.java b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcess.java
new file mode 100644
index 0000000..35a7883
--- /dev/null
+++ b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcess.java
@@ -0,0 +1,72 @@
+/*
+ * 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 javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+@XmlRootElement(name = "bpmnProcess")
+@XmlType
+public class BpmnProcess extends AbstractBaseBean implements EntityTO {
+
+ private static final long serialVersionUID = -7044543391316529128L;
+
+ private String key;
+
+ private String modelId;
+
+ private String name;
+
+ private boolean userWorkflow;
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+
+ @Override
+ public void setKey(final String key) {
+ this.key = key;
+ }
+
+ public String getModelId() {
+ return modelId;
+ }
+
+ public void setModelId(final String modelId) {
+ this.modelId = modelId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public boolean isUserWorkflow() {
+ return userWorkflow;
+ }
+
+ public void setUserWorkflow(final boolean userWorkflow) {
+ this.userWorkflow = userWorkflow;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/6f6d9156/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcessTO.java
----------------------------------------------------------------------
diff --git a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcessTO.java b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcessTO.java
deleted file mode 100644
index bb67e3e..0000000
--- a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/BpmnProcessTO.java
+++ /dev/null
@@ -1,72 +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.to;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-
-@XmlRootElement(name = "bpmnProcess")
-@XmlType
-public class BpmnProcessTO extends AbstractBaseBean implements EntityTO {
-
- private static final long serialVersionUID = -7044543391316529128L;
-
- private String key;
-
- private String modelId;
-
- private String name;
-
- private boolean userWorkflow;
-
- @Override
- public String getKey() {
- return key;
- }
-
- @Override
- public void setKey(final String key) {
- this.key = key;
- }
-
- public String getModelId() {
- return modelId;
- }
-
- public void setModelId(final String modelId) {
- this.modelId = modelId;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(final String name) {
- this.name = name;
- }
-
- public boolean isUserWorkflow() {
- return userWorkflow;
- }
-
- public void setUserWorkflow(final boolean userWorkflow) {
- this.userWorkflow = userWorkflow;
- }
-}
[4/6] syncope git commit: [SYNCOPE-1369] User requests forms now
support dropdowns - via Flowable customization
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserRequestLogic.java
----------------------------------------------------------------------
diff --git a/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserRequestLogic.java b/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserRequestLogic.java
index 1acc1da..686677e 100644
--- a/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserRequestLogic.java
+++ b/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/UserRequestLogic.java
@@ -25,13 +25,12 @@ import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.patch.UserPatch;
import org.apache.syncope.common.lib.to.PropagationTaskTO;
-import org.apache.syncope.common.lib.to.UserRequestTO;
+import org.apache.syncope.common.lib.to.UserRequest;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.to.UserRequestForm;
import org.apache.syncope.common.lib.types.BpmnProcessFormat;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.FlowableEntitlement;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.syncope.core.flowable.api.BpmnProcessManager;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
@@ -41,6 +40,7 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecu
import org.apache.syncope.core.provisioning.api.WorkflowResult;
import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
import org.apache.syncope.core.flowable.api.UserRequestHandler;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
@@ -52,24 +52,49 @@ import org.springframework.transaction.annotation.Transactional;
public class UserRequestLogic extends AbstractTransactionalLogic<UserRequestForm> {
@Autowired
- private BpmnProcessManager bpmnProcessManager;
+ protected BpmnProcessManager bpmnProcessManager;
@Autowired
- private UserRequestHandler userRequestHandler;
+ protected UserRequestHandler userRequestHandler;
@Autowired
- private PropagationManager propagationManager;
+ protected PropagationManager propagationManager;
@Autowired
- private PropagationTaskExecutor taskExecutor;
+ protected PropagationTaskExecutor taskExecutor;
@Autowired
- private UserDataBinder binder;
+ protected UserDataBinder binder;
@Autowired
- private UserDAO userDAO;
+ protected UserDAO userDAO;
- protected UserRequestTO doStart(final String bpmnProcess, final User user) {
+ @PreAuthorize("isAuthenticated()")
+ @Transactional(readOnly = true)
+ public Pair<Integer, List<UserRequest>> list(final String userKey,
+ final int page,
+ final int size,
+ final List<OrderByClause> orderByClauses) {
+
+ if (userKey == null) {
+ securityChecks(null,
+ FlowableEntitlement.USER_REQUEST_LIST,
+ "Listing user requests not allowed");
+ } else {
+ User user = userDAO.find(userKey);
+ if (user == null) {
+ throw new NotFoundException("User " + userKey);
+ }
+
+ securityChecks(user.getUsername(),
+ FlowableEntitlement.USER_REQUEST_LIST,
+ "Listing requests for user" + user.getUsername() + " not allowed");
+ }
+
+ return userRequestHandler.getUserRequests(userKey, page, size, orderByClauses);
+ }
+
+ protected UserRequest doStart(final String bpmnProcess, final User user) {
// check if BPMN process exists
bpmnProcessManager.exportProcess(bpmnProcess, BpmnProcessFormat.XML, new NullOutputStream());
@@ -77,56 +102,84 @@ public class UserRequestLogic extends AbstractTransactionalLogic<UserRequestForm
}
@PreAuthorize("isAuthenticated()")
- public UserRequestTO start(final String bpmnProcess) {
+ public UserRequest start(final String bpmnProcess) {
return doStart(bpmnProcess, userDAO.findByUsername(AuthContextUtils.getUsername()));
}
@PreAuthorize("hasRole('" + FlowableEntitlement.USER_REQUEST_START + "')")
- public UserRequestTO start(final String bpmnProcess, final String userKey) {
+ public UserRequest start(final String bpmnProcess, final String userKey) {
return doStart(bpmnProcess, userDAO.authFind(userKey));
}
- @PreAuthorize("isAuthenticated()")
- public void cancel(final String executionId, final String reason) {
- Pair<ProcessInstance, String> parsed = userRequestHandler.parse(executionId);
-
- if (!AuthContextUtils.getUsername().equals(userDAO.find(parsed.getRight()).getUsername())
+ protected void securityChecks(final String username, final String entitlement, final String errorMessage) {
+ if (!AuthContextUtils.getUsername().equals(username)
&& !AuthContextUtils.getAuthorities().stream().
- anyMatch(auth -> FlowableEntitlement.USER_REQUEST_CANCEL.equals(auth.getAuthority()))) {
+ anyMatch(auth -> entitlement.equals(auth.getAuthority()))) {
SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.DelegatedAdministration);
- sce.getElements().add("Canceling " + executionId + " not allowed");
+ sce.getElements().add(errorMessage);
throw sce;
}
+ }
+
+ @PreAuthorize("isAuthenticated()")
+ public void cancel(final String executionId, final String reason) {
+ Pair<ProcessInstance, String> parsed = userRequestHandler.parse(executionId);
+
+ securityChecks(userDAO.find(parsed.getRight()).getUsername(),
+ FlowableEntitlement.USER_REQUEST_CANCEL,
+ "Canceling " + executionId + " not allowed");
userRequestHandler.cancel(parsed.getLeft(), reason);
}
- @PreAuthorize("hasRole('" + FlowableEntitlement.WORKFLOW_FORM_CLAIM + "')")
+ @PreAuthorize("isAuthenticated()")
public UserRequestForm claimForm(final String taskId) {
- return userRequestHandler.claimForm(taskId);
- }
-
- @PreAuthorize("hasRole('" + FlowableEntitlement.WORKFLOW_FORM_READ + "') "
- + "and hasRole('" + StandardEntitlement.USER_READ + "')")
- @Transactional(readOnly = true)
- public List<UserRequestForm> getForms(final String key) {
- User user = userDAO.authFind(key);
- return userRequestHandler.getForms(user.getKey());
+ UserRequestForm form = userRequestHandler.claimForm(taskId);
+ securityChecks(form.getUsername(),
+ FlowableEntitlement.USER_REQUEST_FORM_CLAIM,
+ "Claiming form " + taskId + " not allowed");
+ return form;
}
- @PreAuthorize("hasRole('" + FlowableEntitlement.WORKFLOW_FORM_LIST + "')")
+ @PreAuthorize("isAuthenticated()")
@Transactional(readOnly = true)
public Pair<Integer, List<UserRequestForm>> getForms(
+ final String userKey,
final int page,
final int size,
final List<OrderByClause> orderByClauses) {
- return userRequestHandler.getForms(page, size, orderByClauses);
+ if (userKey == null) {
+ securityChecks(null,
+ FlowableEntitlement.USER_REQUEST_FORM_LIST,
+ "Listing forms not allowed");
+ } else {
+ User user = userDAO.find(userKey);
+ if (user == null) {
+ throw new NotFoundException("User " + userKey);
+ }
+
+ securityChecks(user.getUsername(),
+ FlowableEntitlement.USER_REQUEST_FORM_LIST,
+ "Listing forms for user" + user.getUsername() + " not allowed");
+ }
+
+ return userRequestHandler.getForms(userKey, page, size, orderByClauses);
}
- @PreAuthorize("hasRole('" + FlowableEntitlement.WORKFLOW_FORM_SUBMIT + "')")
+ @PreAuthorize("isAuthenticated()")
public UserTO submitForm(final UserRequestForm form) {
+ if (form.getUsername() == null) {
+ securityChecks(null,
+ FlowableEntitlement.USER_REQUEST_FORM_SUBMIT,
+ "Submitting forms not allowed");
+ } else {
+ securityChecks(form.getUsername(),
+ FlowableEntitlement.USER_REQUEST_FORM_SUBMIT,
+ "Submitting forms for user" + form.getUsername() + " not allowed");
+ }
+
WorkflowResult<UserPatch> wfResult = userRequestHandler.submitForm(form);
// propByRes can be made empty by the workflow definition if no propagation should occur
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestFormQuery.java
----------------------------------------------------------------------
diff --git a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestFormQuery.java b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestFormQuery.java
index 4097afd..c4ac3a0 100644
--- a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestFormQuery.java
+++ b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestFormQuery.java
@@ -18,6 +18,8 @@
*/
package org.apache.syncope.common.rest.api.beans;
+import javax.ws.rs.QueryParam;
+
public class UserRequestFormQuery extends AbstractQuery {
private static final long serialVersionUID = -4762457303770028554L;
@@ -28,5 +30,21 @@ public class UserRequestFormQuery extends AbstractQuery {
protected UserRequestFormQuery newInstance() {
return new UserRequestFormQuery();
}
+
+ public Builder user(final String user) {
+ getInstance().setUser(user);
+ return this;
+ }
+ }
+
+ private String user;
+
+ public String getUser() {
+ return user;
+ }
+
+ @QueryParam("user")
+ public void setUser(final String user) {
+ this.user = user;
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestQuery.java
----------------------------------------------------------------------
diff --git a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestQuery.java b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestQuery.java
new file mode 100644
index 0000000..3f53629
--- /dev/null
+++ b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/UserRequestQuery.java
@@ -0,0 +1,50 @@
+/*
+ * 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.beans;
+
+import javax.ws.rs.QueryParam;
+
+public class UserRequestQuery extends AbstractQuery {
+
+ private static final long serialVersionUID = 427312034580076640L;
+
+ public static class Builder extends AbstractQuery.Builder<UserRequestQuery, Builder> {
+
+ @Override
+ protected UserRequestQuery newInstance() {
+ return new UserRequestQuery();
+ }
+
+ public Builder user(final String user) {
+ getInstance().setUser(user);
+ return this;
+ }
+ }
+
+ private String user;
+
+ public String getUser() {
+ return user;
+ }
+
+ @QueryParam("user")
+ public void setUser(final String user) {
+ this.user = user;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/BpmnProcessService.java
----------------------------------------------------------------------
diff --git a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/BpmnProcessService.java b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/BpmnProcessService.java
index 06cb056..bb34fdd 100644
--- a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/BpmnProcessService.java
+++ b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/BpmnProcessService.java
@@ -19,6 +19,9 @@
package org.apache.syncope.common.rest.api.service;
import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.ArraySchema;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
@@ -35,7 +38,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.common.rest.api.RESTHeaders;
/**
@@ -51,11 +54,16 @@ public interface BpmnProcessService extends JAXRSService {
/**
* Lists the available BPMN processes.
*
- * @return available BPMN processs, for the given any object type
+ * @return available BPMN processs
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "available BPMN processes", content =
+ @Content(array =
+ @ArraySchema(schema =
+ @Schema(implementation = BpmnProcess.class)))))
@GET
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
- List<BpmnProcessTO> list();
+ List<BpmnProcess> list();
/**
* Exports the BPMN process for matching key.
@@ -63,6 +71,8 @@ public interface BpmnProcessService extends JAXRSService {
* @param key BPMN process key
* @return BPMN process for matching key
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "BPMN process for matching key"))
@GET
@Path("{key}")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@@ -72,8 +82,10 @@ public interface BpmnProcessService extends JAXRSService {
* Exports the BPMN diagram representation (if available), for matching key.
*
* @param key BPMN process key
- * @return workflow diagram representation
+ * @return BPMN diagram representation
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "BPMN diagram representation"))
@GET
@Path("{key}/diagram.png")
@Produces({ RESTHeaders.MEDIATYPE_IMAGE_PNG })
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserRequestService.java
----------------------------------------------------------------------
diff --git a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserRequestService.java b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserRequestService.java
index 701772d..5ad7b12 100644
--- a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserRequestService.java
+++ b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserRequestService.java
@@ -18,10 +18,13 @@
*/
package org.apache.syncope.common.rest.api.service;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.security.SecurityRequirements;
import io.swagger.v3.oas.annotations.tags.Tag;
-import java.util.List;
import javax.validation.constraints.NotNull;
import javax.ws.rs.BeanParam;
import javax.ws.rs.Consumes;
@@ -34,11 +37,12 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.UserRequestTO;
+import org.apache.syncope.common.lib.to.UserRequest;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.to.UserRequestForm;
import org.apache.syncope.common.rest.api.RESTHeaders;
import org.apache.syncope.common.rest.api.beans.UserRequestFormQuery;
+import org.apache.syncope.common.rest.api.beans.UserRequestQuery;
/**
* REST operations related to user workflow.
@@ -51,19 +55,37 @@ import org.apache.syncope.common.rest.api.beans.UserRequestFormQuery;
public interface UserRequestService extends JAXRSService {
/**
- * Starts a new user request, for the given BOMN Process and
- * user (if provided) or requesting user (if not provided).
+ * Returns a list of running user requests matching the given query.
+ *
+ * @param query query conditions
+ * @return list of all running user requests
+ */
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "list of all running user requests", content =
+ @Content(schema =
+ @Schema(implementation = PagedResult.class))))
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ PagedResult<UserRequest> list(@BeanParam UserRequestQuery query);
+
+ /**
+ * Starts a new request for the given BPMN Process and user (if provided) or requesting user (if not provided).
*
* @param bpmnProcess BPMN process
- * @param userKey user key
+ * @param user if value looks like a UUID then it is interpreted as key otherwise as a username
* @return data about the started request service, including execution id
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200",
+ description = "data about the started request service, including execution id", content =
+ @Content(schema =
+ @Schema(implementation = UserRequest.class))))
@POST
@Path("start/{bpmnProcess}")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
- UserRequestTO start(
+ UserRequest start(
@NotNull @PathParam("bpmnProcess") String bpmnProcess,
- @QueryParam("userKey") String userKey);
+ @QueryParam("user") String user);
/**
* Cancel a running user request.
@@ -71,6 +93,8 @@ public interface UserRequestService extends JAXRSService {
* @param executionId execution id
* @param reason reason to cancel the user request
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "204", description = "Operation was successful"))
@DELETE
@Path("{executionId}")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
@@ -79,44 +103,45 @@ public interface UserRequestService extends JAXRSService {
@QueryParam("reason") String reason);
/**
- * Returns a list of all available workflow forms.
+ * Returns a list of user request forms matching the given query.
*
* @param query query conditions
- * @return list of all available workflow forms
+ * @return list of all available user request forms
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "list of all available user request forms", content =
+ @Content(schema =
+ @Schema(implementation = PagedResult.class))))
@GET
@Path("forms")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
PagedResult<UserRequestForm> getForms(@BeanParam UserRequestFormQuery query);
/**
- * Returns a list of available forms for the given user key.
- *
- * @param userKey user key
- * @return list of available forms for the given user key
- */
- @GET
- @Path("forms/{userKey}")
- @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
- List<UserRequestForm> getForms(@NotNull @PathParam("userKey") String userKey);
-
- /**
- * Claims the form for the given task id.
+ * Requests to manage the form for the given task id.
*
* @param taskId workflow task id
- * @return the workflow form for the given task id
+ * @return the form for the given task id
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "the form for the given task id", content =
+ @Content(schema =
+ @Schema(implementation = UserRequestForm.class))))
@POST
@Path("forms/{taskId}/claim")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
UserRequestForm claimForm(@NotNull @PathParam("taskId") String taskId);
/**
- * Submits a workflow form.
+ * Submits a user request form.
*
- * @param form workflow form.
+ * @param form user request form.
* @return updated user
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "updated user", content =
+ @Content(schema =
+ @Schema(implementation = UserTO.class))))
@POST
@Path("forms")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserWorkflowTaskService.java
----------------------------------------------------------------------
diff --git a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserWorkflowTaskService.java b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserWorkflowTaskService.java
index 54f38d0..b396d6e 100644
--- a/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserWorkflowTaskService.java
+++ b/ext/flowable/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserWorkflowTaskService.java
@@ -18,6 +18,11 @@
*/
package org.apache.syncope.common.rest.api.service;
+import io.swagger.v3.oas.annotations.media.ArraySchema;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.security.SecurityRequirements;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -48,6 +53,11 @@ public interface UserWorkflowTaskService extends JAXRSService {
* @param userKey user key
* @return list of available tasks for the given user key
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "list of available tasks for the given user key", content =
+ @Content(array =
+ @ArraySchema(schema =
+ @Schema(implementation = WorkflowTask.class)))))
@GET
@Path("tasks/{userKey}")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
@@ -59,6 +69,10 @@ public interface UserWorkflowTaskService extends JAXRSService {
* @param workflowTaskExecInput input for task execution
* @return updated user
*/
+ @ApiResponses(
+ @ApiResponse(responseCode = "200", description = "updated user", content =
+ @Content(schema =
+ @Schema(implementation = UserTO.class))))
@POST
@Path("tasks/{userKey}")
@Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/BpmnProcessServiceImpl.java
----------------------------------------------------------------------
diff --git a/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/BpmnProcessServiceImpl.java b/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/BpmnProcessServiceImpl.java
index dd1aea8..4f976b5 100644
--- a/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/BpmnProcessServiceImpl.java
+++ b/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/BpmnProcessServiceImpl.java
@@ -22,7 +22,7 @@ import java.util.List;
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.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.common.lib.types.BpmnProcessFormat;
import org.apache.syncope.common.rest.api.RESTHeaders;
import org.apache.syncope.core.logic.BpmnProcessLogic;
@@ -37,7 +37,7 @@ public class BpmnProcessServiceImpl extends AbstractServiceImpl implements BpmnP
private BpmnProcessLogic logic;
@Override
- public List<BpmnProcessTO> list() {
+ public List<BpmnProcess> list() {
return logic.list();
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserRequestServiceImpl.java
----------------------------------------------------------------------
diff --git a/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserRequestServiceImpl.java b/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserRequestServiceImpl.java
index 2f174a0..188d22e 100644
--- a/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserRequestServiceImpl.java
+++ b/ext/flowable/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserRequestServiceImpl.java
@@ -21,14 +21,16 @@ package org.apache.syncope.core.rest.cxf.service;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.UserRequestTO;
+import org.apache.syncope.common.lib.to.UserRequest;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.to.UserRequestForm;
import org.apache.syncope.common.rest.api.beans.UserRequestFormQuery;
+import org.apache.syncope.common.rest.api.beans.UserRequestQuery;
import org.apache.syncope.core.logic.UserRequestLogic;
+import org.apache.syncope.common.rest.api.service.UserRequestService;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
-import org.apache.syncope.common.rest.api.service.UserRequestService;
@Service
public class UserRequestServiceImpl extends AbstractServiceImpl implements UserRequestService {
@@ -36,11 +38,25 @@ public class UserRequestServiceImpl extends AbstractServiceImpl implements UserR
@Autowired
private UserRequestLogic logic;
+ @Autowired
+ private UserDAO userDAO;
+
+ @Override
+ public PagedResult<UserRequest> list(final UserRequestQuery query) {
+ if (query.getUser() != null) {
+ query.setUser(getActualKey(userDAO, query.getUser()));
+ }
+
+ Pair<Integer, List<UserRequest>> result = logic.list(
+ query.getUser(), query.getPage(), query.getSize(), getOrderByClauses(query.getOrderBy()));
+ return buildPagedResult(result.getRight(), query.getPage(), query.getSize(), result.getLeft());
+ }
+
@Override
- public UserRequestTO start(final String bpmnProcess, final String userKey) {
- return userKey == null
+ public UserRequest start(final String bpmnProcess, final String user) {
+ return user == null
? logic.start(bpmnProcess)
- : logic.start(bpmnProcess, userKey);
+ : logic.start(bpmnProcess, getActualKey(userDAO, user));
}
@Override
@@ -54,14 +70,13 @@ public class UserRequestServiceImpl extends AbstractServiceImpl implements UserR
}
@Override
- public List<UserRequestForm> getForms(final String userKey) {
- return logic.getForms(userKey);
- }
-
- @Override
public PagedResult<UserRequestForm> getForms(final UserRequestFormQuery query) {
+ if (query.getUser() != null) {
+ query.setUser(getActualKey(userDAO, query.getUser()));
+ }
+
Pair<Integer, List<UserRequestForm>> result = logic.getForms(
- query.getPage(), query.getSize(), getOrderByClauses(query.getOrderBy()));
+ query.getUser(), query.getPage(), query.getSize(), getOrderByClauses(query.getOrderBy()));
return buildPagedResult(result.getRight(), query.getPage(), query.getSize(), result.getLeft());
}
@@ -69,5 +84,4 @@ public class UserRequestServiceImpl extends AbstractServiceImpl implements UserR
public UserTO submitForm(final UserRequestForm form) {
return logic.submitForm(form);
}
-
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/fit/core-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index c89241e..dc5e8d1 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -1541,6 +1541,26 @@ under the License.
<build>
<plugins>
+ <!-- Adds Flowable custom classes -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>add-flowable-custom-classes</id>
+ <phase>initialize</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${basedir}/src/main/java-all</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
<!-- Adds Flowable test content -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/AssignDirectorGroup.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/AssignDirectorGroup.java b/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/AssignDirectorGroup.java
new file mode 100644
index 0000000..4db7ac2
--- /dev/null
+++ b/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/AssignDirectorGroup.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.fit.core.reference.flowable;
+
+import org.apache.syncope.common.lib.patch.MembershipPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.core.flowable.impl.FlowableRuntimeUtils;
+import org.apache.syncope.core.flowable.task.AbstractFlowableServiceTask;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.PropagationByResource;
+import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AssignDirectorGroup extends AbstractFlowableServiceTask {
+
+ @Autowired
+ private UserDataBinder dataBinder;
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Override
+ protected void doExecute(final String executionId) {
+ User user = engine.getRuntimeService().
+ getVariable(executionId, FlowableRuntimeUtils.USER, User.class);
+
+ Boolean secondLevelApprove = engine.getRuntimeService().
+ getVariable(executionId, "secondLevelApprove", Boolean.class);
+ if (Boolean.TRUE.equals(secondLevelApprove)) {
+ user = userDAO.save(user);
+
+ UserPatch userPatch = new UserPatch();
+ userPatch.setKey(user.getKey());
+ userPatch.getMemberships().add(new MembershipPatch.Builder().
+ group("ebf97068-aa4b-4a85-9f01-680e8c4cf227").build());
+
+ PropagationByResource propByRes = dataBinder.update(user, userPatch);
+
+ // report updated user and propagation by resource as result
+ engine.getRuntimeService().setVariable(executionId, FlowableRuntimeUtils.USER, user);
+ engine.getRuntimeService().setVariable(executionId, FlowableRuntimeUtils.PROP_BY_RESOURCE, propByRes);
+ } else {
+ LOG.info("Second level was not approved, not assigning the director group to " + user.getUsername());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/CreateARelationship.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/CreateARelationship.java b/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/CreateARelationship.java
new file mode 100644
index 0000000..b0c5261
--- /dev/null
+++ b/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/CreateARelationship.java
@@ -0,0 +1,71 @@
+/*
+ * 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.fit.core.reference.flowable;
+
+import org.apache.syncope.common.lib.patch.RelationshipPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.RelationshipTO;
+import org.apache.syncope.core.flowable.impl.FlowableRuntimeUtils;
+import org.apache.syncope.core.flowable.task.AbstractFlowableServiceTask;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.PropagationByResource;
+import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class CreateARelationship extends AbstractFlowableServiceTask {
+
+ @Autowired
+ private UserDataBinder dataBinder;
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Override
+ protected void doExecute(final String executionId) {
+ User user = engine.getRuntimeService().
+ getVariable(executionId, FlowableRuntimeUtils.USER, User.class);
+
+ Boolean approve = engine.getRuntimeService().
+ getVariable(executionId, "approve", Boolean.class);
+ if (Boolean.TRUE.equals(approve)) {
+ user = userDAO.save(user);
+
+ String printer = engine.getRuntimeService().
+ getVariable(executionId, "printer", String.class);
+
+ UserPatch userPatch = new UserPatch();
+ userPatch.setKey(user.getKey());
+ userPatch.getRelationships().add(new RelationshipPatch.Builder().
+ relationshipTO(new RelationshipTO.Builder().
+ otherEnd("PRINTER", printer).type("neighborhood").build()).
+ build());
+
+ PropagationByResource propByRes = dataBinder.update(user, userPatch);
+
+ // report updated user and propagation by resource as result
+ engine.getRuntimeService().setVariable(executionId, FlowableRuntimeUtils.USER, user);
+ engine.getRuntimeService().setVariable(executionId, FlowableRuntimeUtils.PROP_BY_RESOURCE, propByRes);
+ } else {
+ LOG.info("Printer assignment to " + user.getUsername() + " was not approved");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/PrintersValueProvider.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/PrintersValueProvider.java b/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/PrintersValueProvider.java
new file mode 100644
index 0000000..82e9693
--- /dev/null
+++ b/fit/core-reference/src/main/java-all/org/apache/syncope/fit/core/reference/flowable/PrintersValueProvider.java
@@ -0,0 +1,70 @@
+/*
+ * 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.fit.core.reference.flowable;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.flowable.api.DropdownValueProvider;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+public class PrintersValueProvider implements DropdownValueProvider {
+
+ private static final SearchCond PRINTER_COND;
+
+ private static final List<OrderByClause> ORDER_BY;
+
+ static {
+ AnyTypeCond anyTypeCond = new AnyTypeCond();
+ anyTypeCond.setAnyTypeKey("PRINTER");
+ PRINTER_COND = SearchCond.getLeafCond(anyTypeCond);
+
+ OrderByClause orderByNameAsc = new OrderByClause();
+ orderByNameAsc.setField("name");
+ orderByNameAsc.setDirection(OrderByClause.Direction.ASC);
+ ORDER_BY = Collections.singletonList(orderByNameAsc);
+ }
+
+ @Autowired
+ private AnySearchDAO anySearchDAO;
+
+ @Transactional(readOnly = true)
+ @Override
+ public Map<String, String> getValues() {
+ return anySearchDAO.<AnyObject>search(PRINTER_COND, ORDER_BY, AnyTypeKind.ANY_OBJECT).stream().
+ collect(Collectors.toMap(
+ AnyObject::getKey,
+ AnyObject::getName,
+ (u, v) -> {
+ throw new IllegalStateException(String.format("Duplicate key %s", u));
+ },
+ LinkedHashMap::new));
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/AssignDirectorGroup.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/AssignDirectorGroup.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/AssignDirectorGroup.java
deleted file mode 100644
index abdfcb6..0000000
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/AssignDirectorGroup.java
+++ /dev/null
@@ -1,63 +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.fit.core.reference;
-
-import org.apache.syncope.common.lib.patch.MembershipPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.core.flowable.impl.FlowableRuntimeUtils;
-import org.apache.syncope.core.flowable.task.AbstractFlowableServiceTask;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.PropagationByResource;
-import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class AssignDirectorGroup extends AbstractFlowableServiceTask {
-
- @Autowired
- private UserDataBinder dataBinder;
-
- @Autowired
- private UserDAO userDAO;
-
- @Override
- protected void doExecute(final String executionId) {
- User user = engine.getRuntimeService().
- getVariable(executionId, FlowableRuntimeUtils.USER, User.class);
-
- Boolean secondLevelApprove = engine.getRuntimeService().
- getVariable(executionId, "secondLevelApprove", Boolean.class);
- if (Boolean.TRUE.equals(secondLevelApprove)) {
- user = userDAO.save(user);
-
- UserPatch userPatch = new UserPatch();
- userPatch.setKey(user.getKey());
- userPatch.getMemberships().add(new MembershipPatch.Builder().
- group("ebf97068-aa4b-4a85-9f01-680e8c4cf227").build());
-
- PropagationByResource propByRes = dataBinder.update(user, userPatch);
-
- // report updated user and propagation by resource as result
- engine.getRuntimeService().setVariable(executionId, FlowableRuntimeUtils.USER, user);
- engine.getRuntimeService().setVariable(executionId, FlowableRuntimeUtils.PROP_BY_RESOURCE, propByRes);
- } else {
- LOG.info("Second level was not approved, not assigning the director group to " + user.getUsername());
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/fit/core-reference/src/main/resources/all/workflowTestContext.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/all/workflowTestContext.xml b/fit/core-reference/src/main/resources/all/workflowTestContext.xml
index 2329c53..b14490a 100644
--- a/fit/core-reference/src/main/resources/all/workflowTestContext.xml
+++ b/fit/core-reference/src/main/resources/all/workflowTestContext.xml
@@ -19,9 +19,12 @@ under the License.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context.xsd">
- <bean id="assignDirectorGroup" class="org.apache.syncope.fit.core.reference.AssignDirectorGroup"/>
+ <context:component-scan base-package="org.apache.syncope.fit.core.reference.flowable"/>
</beans>
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/fit/core-reference/src/main/resources/assignPrinterRequest.bpmn20.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/assignPrinterRequest.bpmn20.xml b/fit/core-reference/src/main/resources/assignPrinterRequest.bpmn20.xml
new file mode 100644
index 0000000..c9ecb9c
--- /dev/null
+++ b/fit/core-reference/src/main/resources/assignPrinterRequest.bpmn20.xml
@@ -0,0 +1,92 @@
+<?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:flowable="http://flowable.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://www.flowable.org/processdef">
+
+ <process id="assignPrinterRequest" name="Assign printer" isExecutable="true">
+ <startEvent id="startevent1" name="Start"/>
+ <endEvent id="endevent1" name="End"/>
+ <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="selectPrinter"/>
+ <userTask id="selectPrinter" name="Select printer" flowable:formKey="selectPrinter" flowable:assignee="${wfExecutor}">
+ <extensionElements>
+ <flowable:formProperty id="printer" name="Printer" variable="printer" type="dropdown" required="true">
+ <flowable:value id="dropdownValueProvider" name="printersValueProvider"/>
+ </flowable:formProperty>
+ <flowable:formProperty id="printMode" name="Preferred print mode?" type="enum">
+ <flowable:value id="bw" name="Black / White"/>
+ <flowable:value id="color" name="Color"/>
+ </flowable:formProperty>
+ </extensionElements>
+ </userTask>
+ <userTask id="approvePrinter" name="Approve printer" flowable:formKey="approvePrinter">
+ <extensionElements>
+ <flowable:formProperty id="username" name="Username" type="string" expression="${userTO.username}" writable="false"/>
+ <flowable:formProperty id="printer" name="Selected printer" type="string" expression="${printer}" writable="false"/>
+ <flowable:formProperty id="approve" name="Approve?" type="boolean" variable="approve" required="true"/>
+ </extensionElements>
+ </userTask>
+ <sequenceFlow id="sid-D7047714-8E57-46B8-B6D4-4844DE330329" sourceRef="selectPrinter" targetRef="approvePrinter"/>
+ <serviceTask id="createARelationship" name="Create ARelationship" flowable:expression="#{createARelationship.execute(execution.processInstanceId)}"/>
+ <sequenceFlow id="sid-33880AE7-35C6-4A39-8E5B-12D8BA53F042" sourceRef="approvePrinter" targetRef="createARelationship"/>
+ <sequenceFlow id="sid-831E1896-EDF9-4F7D-AA42-E86CC1F8C5D3" sourceRef="createARelationship" targetRef="endevent1"/>
+ </process>
+ <bpmndi:BPMNDiagram id="BPMNDiagram_assignPrinterRequest">
+ <bpmndi:BPMNPlane bpmnElement="assignPrinterRequest" id="BPMNPlane_assignPrinterRequest">
+ <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
+ <omgdc:Bounds height="30.0" width="30.0" x="180.0" y="115.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
+ <omgdc:Bounds height="28.0" width="28.0" x="885.0" y="116.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="selectPrinter" id="BPMNShape_selectPrinter">
+ <omgdc:Bounds height="80.0" width="100.0" x="330.0" y="90.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="approvePrinter" id="BPMNShape_approvePrinter">
+ <omgdc:Bounds height="80.0" width="100.0" x="495.5" y="90.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="createARelationship" id="BPMNShape_createARelationship">
+ <omgdc:Bounds height="80.0" width="100.0" x="675.0" y="90.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
+ <omgdi:waypoint x="209.94999901196195" y="130.0"/>
+ <omgdi:waypoint x="330.0" y="130.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="sid-D7047714-8E57-46B8-B6D4-4844DE330329" id="BPMNEdge_sid-D7047714-8E57-46B8-B6D4-4844DE330329">
+ <omgdi:waypoint x="429.95000000000005" y="130.0"/>
+ <omgdi:waypoint x="495.5" y="130.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="sid-33880AE7-35C6-4A39-8E5B-12D8BA53F042" id="BPMNEdge_sid-33880AE7-35C6-4A39-8E5B-12D8BA53F042">
+ <omgdi:waypoint x="595.4499999999068" y="130.0"/>
+ <omgdi:waypoint x="675.0" y="130.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="sid-831E1896-EDF9-4F7D-AA42-E86CC1F8C5D3" id="BPMNEdge_sid-831E1896-EDF9-4F7D-AA42-E86CC1F8C5D3">
+ <omgdi:waypoint x="774.9499999999266" y="130.0"/>
+ <omgdi:waypoint x="885.0" y="130.0"/>
+ </bpmndi:BPMNEdge>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+</definitions>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
index e2f351b..cbdb19b 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuthenticationITCase.java
@@ -66,6 +66,7 @@ import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.syncope.common.lib.types.StatusPatchType;
import org.apache.syncope.common.rest.api.RESTHeaders;
import org.apache.syncope.common.rest.api.beans.AnyQuery;
+import org.apache.syncope.common.rest.api.beans.UserRequestFormQuery;
import org.apache.syncope.common.rest.api.service.AnyObjectService;
import org.apache.syncope.common.rest.api.service.SchemaService;
import org.apache.syncope.common.rest.api.service.UserService;
@@ -495,7 +496,8 @@ public class AuthenticationITCase extends AbstractITCase {
}
// 3. approve user
- UserRequestForm form = userRequestService.getForms(userTO.getKey()).get(0);
+ UserRequestForm form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(userTO.getKey()).build()).getResult().get(0);
form = userRequestService.claimForm(form.getTaskId());
form.getProperty("approveCreate").get().setValue(Boolean.TRUE.toString());
userTO = userRequestService.submitForm(form);
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/fit/core-reference/src/test/java/org/apache/syncope/fit/core/BpmnProcessITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/BpmnProcessITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/BpmnProcessITCase.java
index 443cd83..21fb4fd 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/BpmnProcessITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/BpmnProcessITCase.java
@@ -28,7 +28,7 @@ import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import javax.ws.rs.core.Response;
import org.apache.commons.io.IOUtils;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.fit.AbstractITCase;
import org.apache.syncope.fit.FlowableDetector;
import org.junit.jupiter.api.BeforeAll;
@@ -42,7 +42,7 @@ public class BpmnProcessITCase extends AbstractITCase {
public static void findDefault() {
assumeTrue(FlowableDetector.isFlowableEnabledForUserWorkflow(syncopeService));
bpmnProcessService.list().stream().
- filter(BpmnProcessTO::isUserWorkflow).findAny().
+ filter(BpmnProcess::isUserWorkflow).findAny().
ifPresent(process -> {
userWorkflowKey = process.getKey();
});
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserRequestITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserRequestITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserRequestITCase.java
index 5446894..9281bce 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserRequestITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserRequestITCase.java
@@ -25,14 +25,19 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import java.io.IOException;
+import java.util.List;
import javax.ws.rs.core.MediaType;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.syncope.client.lib.SyncopeClient;
import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.RelationshipTO;
import org.apache.syncope.common.lib.to.UserRequestForm;
-import org.apache.syncope.common.lib.to.UserRequestTO;
+import org.apache.syncope.common.lib.to.UserRequest;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.rest.api.beans.UserRequestFormQuery;
+import org.apache.syncope.common.rest.api.beans.UserRequestQuery;
+import org.apache.syncope.common.rest.api.service.UserRequestService;
import org.apache.syncope.fit.AbstractITCase;
import org.apache.syncope.fit.FlowableDetector;
import org.junit.jupiter.api.BeforeAll;
@@ -42,9 +47,13 @@ public class UserRequestITCase extends AbstractITCase {
@BeforeAll
public static void loadBpmnProcesses() throws IOException {
+ assumeTrue(FlowableDetector.isFlowableEnabledForUserWorkflow(syncopeService));
+
WebClient.client(bpmnProcessService).type(MediaType.APPLICATION_XML_TYPE);
bpmnProcessService.set("directorGroupRequest",
IOUtils.toString(UserRequestITCase.class.getResourceAsStream("/directorGroupRequest.bpmn20.xml")));
+ bpmnProcessService.set("assignPrinterRequest",
+ IOUtils.toString(UserRequestITCase.class.getResourceAsStream("/assignPrinterRequest.bpmn20.xml")));
}
@Test
@@ -56,17 +65,29 @@ public class UserRequestITCase extends AbstractITCase {
assertFalse(user.getMembership("ebf97068-aa4b-4a85-9f01-680e8c4cf227").isPresent());
// start request
- UserRequestTO req = userRequestService.start("directorGroupRequest", user.getKey());
+ UserRequest req = userRequestService.start("directorGroupRequest", user.getKey());
assertNotNull(req);
+ assertEquals("directorGroupRequest", req.getBpmnProcess());
+ assertNotNull(req.getExecutionId());
+ assertEquals(req.getUser(), user.getKey());
+
+ // check that user can see the ongoing request
+ SyncopeClient client = clientFactory.create(user.getUsername(), "password123");
+ PagedResult<UserRequest> requests = client.getService(UserRequestService.class).
+ list(new UserRequestQuery.Builder().user(user.getKey()).build());
+ assertEquals(1, requests.getTotalCount());
+ assertEquals("directorGroupRequest", requests.getResult().get(0).getBpmnProcess());
// 1st approval -> reject
- UserRequestForm form = userRequestService.getForms(user.getKey()).get(0);
+ UserRequestForm form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().get(0);
form = userRequestService.claimForm(form.getTaskId());
form.getProperty("firstLevelApprove").get().setValue(Boolean.FALSE.toString());
userRequestService.submitForm(form);
// no more forms, group not assigned
- assertTrue(userRequestService.getForms(user.getKey()).isEmpty());
+ assertTrue(userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().isEmpty());
assertFalse(userService.read(user.getKey()).getMembership("ebf97068-aa4b-4a85-9f01-680e8c4cf227").isPresent());
// start request again
@@ -74,19 +95,22 @@ public class UserRequestITCase extends AbstractITCase {
assertNotNull(req);
// 1st approval -> accept
- form = userRequestService.getForms(user.getKey()).get(0);
+ form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().get(0);
form = userRequestService.claimForm(form.getTaskId());
form.getProperty("firstLevelApprove").get().setValue(Boolean.TRUE.toString());
userRequestService.submitForm(form);
// 2nd approval -> reject
- form = userRequestService.getForms(user.getKey()).get(0);
+ form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().get(0);
form = userRequestService.claimForm(form.getTaskId());
form.getProperty("secondLevelApprove").get().setValue(Boolean.FALSE.toString());
user = userRequestService.submitForm(form);
// no more forms, group not assigned
- assertTrue(userRequestService.getForms(user.getKey()).isEmpty());
+ assertTrue(userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().isEmpty());
assertFalse(userService.read(user.getKey()).getMembership("ebf97068-aa4b-4a85-9f01-680e8c4cf227").isPresent());
// start request again
@@ -94,13 +118,15 @@ public class UserRequestITCase extends AbstractITCase {
assertNotNull(req);
// 1st approval -> accept
- form = userRequestService.getForms(user.getKey()).get(0);
+ form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().get(0);
form = userRequestService.claimForm(form.getTaskId());
form.getProperty("firstLevelApprove").get().setValue(Boolean.TRUE.toString());
userRequestService.submitForm(form);
// 2nd approval -> accept
- form = userRequestService.getForms(user.getKey()).get(0);
+ form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().get(0);
form = userRequestService.claimForm(form.getTaskId());
form.getProperty("secondLevelApprove").get().setValue(Boolean.TRUE.toString());
user = userRequestService.submitForm(form);
@@ -115,7 +141,7 @@ public class UserRequestITCase extends AbstractITCase {
assumeTrue(FlowableDetector.isFlowableEnabledForUserWorkflow(syncopeService));
PagedResult<UserRequestForm> forms =
- userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build());
+ userRequestService.getForms(new UserRequestFormQuery.Builder().build());
int preForms = forms.getTotalCount();
UserTO user = createUser(UserITCase.getUniqueSampleTO("twoLevelsApproval@tirasa.net")).getEntity();
@@ -123,22 +149,101 @@ public class UserRequestITCase extends AbstractITCase {
assertFalse(user.getMembership("ebf97068-aa4b-4a85-9f01-680e8c4cf227").isPresent());
// start request
- UserRequestTO req = userRequestService.start("directorGroupRequest", user.getKey());
+ UserRequest req = userRequestService.start("directorGroupRequest", user.getKey());
assertNotNull(req);
// check that form was generated
- forms = userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build());
+ forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
assertEquals(preForms + 1, forms.getTotalCount());
- assertEquals(1, userRequestService.getForms(user.getKey()).size());
+ assertEquals(1, userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().size());
// cancel request
userRequestService.cancel(req.getExecutionId(), "nothing in particular");
// check that form was removed
- forms = userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build());
+ forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
+ assertEquals(preForms, forms.getTotalCount());
+
+ assertTrue(userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().isEmpty());
+ }
+
+ @Test
+ public void userSelection() {
+ assumeTrue(FlowableDetector.isFlowableEnabledForUserWorkflow(syncopeService));
+
+ assumeTrue(FlowableDetector.isFlowableEnabledForUserWorkflow(syncopeService));
+
+ PagedResult<UserRequestForm> forms =
+ userRequestService.getForms(new UserRequestFormQuery.Builder().build());
+ int preForms = forms.getTotalCount();
+
+ UserTO user = createUser(UserITCase.getUniqueSampleTO("userSelection@tirasa.net")).getEntity();
+ assertNotNull(user);
+ List<RelationshipTO> relationships = userService.read(user.getKey()).getRelationships();
+ assertTrue(relationships.isEmpty());
+
+ SyncopeClient client = clientFactory.create(user.getUsername(), "password123");
+
+ // start request as user
+ UserRequest req = client.getService(UserRequestService.class).start("assignPrinterRequest", null);
+ assertNotNull(req);
+
+ // check (as admin) that a new form is available
+ forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
+ assertEquals(preForms + 1, forms.getTotalCount());
+
+ // get (as user) the form, claim and submit
+ PagedResult<UserRequestForm> userForms = client.getService(UserRequestService.class).
+ getForms(new UserRequestFormQuery.Builder().user(user.getKey()).build());
+ assertEquals(1, userForms.getTotalCount());
+
+ UserRequestForm form = userForms.getResult().get(0);
+ assertEquals("assignPrinterRequest", form.getBpmnProcess());
+ form = client.getService(UserRequestService.class).claimForm(form.getTaskId());
+
+ assertFalse(form.getProperty("printer").get().getDropdownValues().isEmpty());
+ form.getProperty("printer").ifPresent(printer -> printer.setValue("8559d14d-58c2-46eb-a2d4-a7d35161e8f8"));
+
+ assertFalse(form.getProperty("printMode").get().getEnumValues().isEmpty());
+ form.getProperty("printMode").ifPresent(printMode -> printMode.setValue("color"));
+
+ client.getService(UserRequestService.class).submitForm(form);
+
+ userForms = client.getService(UserRequestService.class).getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build());
+ assertEquals(0, userForms.getTotalCount());
+
+ // check that user can see the ongoing request
+ PagedResult<UserRequest> requests = client.getService(UserRequestService.class).
+ list(new UserRequestQuery.Builder().user(user.getKey()).build());
+ assertEquals(1, requests.getTotalCount());
+ assertEquals("assignPrinterRequest", requests.getResult().get(0).getBpmnProcess());
+
+ // get (as admin) the new form, claim and submit
+ form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(user.getKey()).build()).getResult().get(0);
+ assertEquals("assignPrinterRequest", form.getBpmnProcess());
+ form = userRequestService.claimForm(form.getTaskId());
+
+ assertEquals("8559d14d-58c2-46eb-a2d4-a7d35161e8f8", form.getProperty("printer").get().getValue());
+
+ form.getProperty("approve").get().setValue(Boolean.TRUE.toString());
+ userRequestService.submitForm(form);
+
+ // no more forms available
+ forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
assertEquals(preForms, forms.getTotalCount());
- assertTrue(userRequestService.getForms(user.getKey()).isEmpty());
+ assertTrue(client.getService(UserRequestService.class).
+ list(new UserRequestQuery.Builder().user(user.getKey()).build()).getResult().isEmpty());
+
+ // check that relationship was made effective by approval
+ relationships = userService.read(user.getKey()).getRelationships();
+ assertFalse(relationships.isEmpty());
+ assertTrue(relationships.stream().
+ anyMatch(relationship -> "8559d14d-58c2-46eb-a2d4-a7d35161e8f8".equals(relationship.getOtherEndKey())));
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java
index 0e48cf2..63db20e 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java
@@ -130,7 +130,8 @@ public class UserSelfITCase extends AbstractITCase {
}
// now approve and verify that propagation has happened
- UserRequestForm form = userRequestService.getForms(userTO.getKey()).get(0);
+ UserRequestForm form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(userTO.getKey()).build()).getResult().get(0);
form = userRequestService.claimForm(form.getTaskId());
form.getProperty("approveCreate").get().setValue(Boolean.TRUE.toString());
userTO = userRequestService.submitForm(form);
@@ -228,7 +229,8 @@ public class UserSelfITCase extends AbstractITCase {
}
// 3. approve self-update as admin
- UserRequestForm form = userRequestService.getForms(updated.getKey()).get(0);
+ UserRequestForm form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(updated.getKey()).build()).getResult().get(0);
form = userRequestService.claimForm(form.getTaskId());
form.getProperty("approveUpdate").get().setValue(Boolean.TRUE.toString());
updated = userRequestService.submitForm(form);
@@ -420,7 +422,8 @@ public class UserSelfITCase extends AbstractITCase {
assertEquals("createApproval", userTO.getStatus());
// 2. request if there is any pending task for user just created
- UserRequestForm form = userRequestService.getForms(userTO.getKey()).get(0);
+ UserRequestForm form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(userTO.getKey()).build()).getResult().get(0);
assertNotNull(form);
assertNotNull(form.getUsername());
assertEquals(userTO.getUsername(), form.getUsername());
@@ -480,8 +483,7 @@ public class UserSelfITCase extends AbstractITCase {
assumeTrue(FlowableDetector.isFlowableEnabledForUserWorkflow(syncopeService));
// read forms *before* any operation
- PagedResult<UserRequestForm> forms =
- userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build());
+ PagedResult<UserRequestForm> forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
int preForms = forms.getTotalCount();
UserTO userTO = UserITCase.getUniqueSampleTO("createWithApproval@syncope.apache.org");
@@ -514,7 +516,7 @@ public class UserSelfITCase extends AbstractITCase {
assertNotNull(exception);
// 2. request if there is any pending form for user just created
- forms = userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build());
+ forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
assertEquals(preForms + 1, forms.getTotalCount());
// 3. as admin, update user: still pending approval
@@ -524,7 +526,8 @@ public class UserSelfITCase extends AbstractITCase {
userPatch.setUsername(new StringReplacePatchItem.Builder().value(updatedUsername).build());
updateUser(userPatch);
- UserRequestForm form = userRequestService.getForms(userTO.getKey()).get(0);
+ UserRequestForm form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(userTO.getKey()).build()).getResult().get(0);
assertNotNull(form);
assertNotNull(form.getTaskId());
assertNotNull(form.getUserTO());
@@ -567,8 +570,8 @@ public class UserSelfITCase extends AbstractITCase {
assumeTrue(FlowableDetector.isFlowableEnabledForUserWorkflow(syncopeService));
// read forms *before* any operation
- PagedResult<UserRequestForm> forms = userRequestService.getForms(new UserRequestFormQuery.Builder().
- page(1).size(1000).build());
+ PagedResult<UserRequestForm> forms = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().build());
int preForms = forms.getTotalCount();
UserTO created = createUser(UserITCase.getUniqueSampleTO("updateApproval@syncope.apache.org")).getEntity();
@@ -585,10 +588,11 @@ public class UserSelfITCase extends AbstractITCase {
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
assertEquals("updateApproval", userService.read(created.getKey()).getStatus());
- forms = userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build());
+ forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
assertEquals(preForms + 1, forms.getTotalCount());
- UserRequestForm form = userRequestService.getForms(created.getKey()).get(0);
+ UserRequestForm form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(created.getKey()).build()).getResult().get(0);
assertNotNull(form);
assertNotNull(form.getTaskId());
assertNull(form.getOwner());
@@ -607,7 +611,8 @@ public class UserSelfITCase extends AbstractITCase {
assertEquals(0, updated.getMemberships().size());
// the patch is not updated in the approval form
- form = userRequestService.getForms(created.getKey()).get(0);
+ form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(created.getKey()).build()).getResult().get(0);
assertEquals(patch, form.getUserPatch());
// approve the user
@@ -642,8 +647,7 @@ public class UserSelfITCase extends AbstractITCase {
assumeTrue(FlowableDetector.isFlowableEnabledForUserWorkflow(syncopeService));
// read forms *before* any operation
- PagedResult<UserRequestForm> forms = userRequestService.getForms(new UserRequestFormQuery.Builder().
- page(1).size(1000).build());
+ PagedResult<UserRequestForm> forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
int preForms = forms.getTotalCount();
UserTO userTO = UserITCase.getUniqueSampleTO("issueSYNCOPE15@syncope.apache.org");
@@ -667,10 +671,11 @@ public class UserSelfITCase extends AbstractITCase {
assertEquals(userTO.getCreationDate(), userTO.getLastChangeDate());
// 2. request if there is any pending form for user just created
- forms = userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build());
+ forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
assertEquals(preForms + 1, forms.getTotalCount());
- UserRequestForm form = userRequestService.getForms(userTO.getKey()).get(0);
+ UserRequestForm form = userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(userTO.getKey()).build()).getResult().get(0);
assertNotNull(form);
// 3. first claim by bellini ....
@@ -692,12 +697,12 @@ public class UserSelfITCase extends AbstractITCase {
userTO = userRequestService.submitForm(form);
assertNotNull(userTO);
assertEquals(preForms,
- userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build()).
- getTotalCount());
- assertTrue(userRequestService.getForms(userTO.getKey()).isEmpty());
+ userRequestService.getForms(new UserRequestFormQuery.Builder().build()).getTotalCount());
+ assertTrue(userRequestService.getForms(
+ new UserRequestFormQuery.Builder().user(userTO.getKey()).build()).getResult().isEmpty());
// 7.check that no more forms are still to be processed
- forms = userRequestService.getForms(new UserRequestFormQuery.Builder().page(1).size(1000).build());
+ forms = userRequestService.getForms(new UserRequestFormQuery.Builder().build());
assertEquals(preForms, forms.getTotalCount());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index edc38b0..a04a9e5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1748,6 +1748,12 @@ under the License.
</plugin>
<plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>3.0.0</version>
+ </plugin>
+
+ <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
@@ -2305,8 +2311,8 @@ under the License.
<link>https://docs.spring.io/spring-security/site/docs/5.0.x/api/</link>
<link>http://www.flowable.org/docs/javadocs/</link>
<link>https://build.shibboleth.net/nexus/content/sites/site/java-opensaml/3.3.0/apidocs/</link>
- <link>https://artifacts.elastic.co/javadoc/org/elasticsearch/elasticsearch/6.4.1/index.html</link>
- <link>http://docs.swagger.io/swagger-core/v2.0.5/apidocs/</link>
+ <link>https://artifacts.elastic.co/javadoc/org/elasticsearch/elasticsearch/6.4.1/index.html</link>
+ <link>http://docs.swagger.io/swagger-core/v2.0.5/apidocs/</link>
</links>
</configuration>
<reportSets>
[5/6] syncope git commit: [SYNCOPE-1369] User requests forms now
support dropdowns - via Flowable customization
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequest.java
----------------------------------------------------------------------
diff --git a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequest.java b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequest.java
new file mode 100644
index 0000000..251eb89
--- /dev/null
+++ b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequest.java
@@ -0,0 +1,70 @@
+/*
+ * 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 javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+@XmlRootElement(name = "userRequest")
+@XmlType
+public class UserRequest extends AbstractBaseBean {
+
+ private static final long serialVersionUID = -8430826310789942133L;
+
+ private String bpmnProcess;
+
+ private String user;
+
+ private String executionId;
+
+ private String activityId;
+
+ public String getBpmnProcess() {
+ return bpmnProcess;
+ }
+
+ public void setBpmnProcess(final String bpmnProcess) {
+ this.bpmnProcess = bpmnProcess;
+ }
+
+ public String getUser() {
+ return user;
+ }
+
+ public void setUser(final String user) {
+ this.user = user;
+ }
+
+ public String getExecutionId() {
+ return executionId;
+ }
+
+ public void setExecutionId(final String executionId) {
+ this.executionId = executionId;
+ }
+
+ public String getActivityId() {
+ return activityId;
+ }
+
+ public void setActivityId(final String activityId) {
+ this.activityId = activityId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestForm.java
----------------------------------------------------------------------
diff --git a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestForm.java b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestForm.java
index 897cfc0..22118b5 100644
--- a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestForm.java
+++ b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestForm.java
@@ -37,8 +37,12 @@ public class UserRequestForm extends AbstractBaseBean {
private static final long serialVersionUID = -7044543391316529128L;
+ private String bpmnProcess;
+
private String username;
+ private String executionId;
+
private String taskId;
private String formKey;
@@ -55,6 +59,14 @@ public class UserRequestForm extends AbstractBaseBean {
private final List<UserRequestFormProperty> properties = new ArrayList<>();
+ public String getBpmnProcess() {
+ return bpmnProcess;
+ }
+
+ public void setBpmnProcess(final String bpmnProcess) {
+ this.bpmnProcess = bpmnProcess;
+ }
+
public String getUsername() {
return username;
}
@@ -63,6 +75,14 @@ public class UserRequestForm extends AbstractBaseBean {
this.username = username;
}
+ public String getExecutionId() {
+ return executionId;
+ }
+
+ public void setExecutionId(final String executionId) {
+ this.executionId = executionId;
+ }
+
public String getTaskId() {
return taskId;
}
@@ -138,9 +158,9 @@ public class UserRequestForm extends AbstractBaseBean {
return properties.stream().filter(property -> id.equals(property.getId())).findFirst();
}
- @XmlElementWrapper(name = "workflowFormProperties")
- @XmlElement(name = "workflowFormProperty")
- @JsonProperty("workflowFormProperties")
+ @XmlElementWrapper(name = "properties")
+ @XmlElement(name = "property")
+ @JsonProperty("properties")
public List<UserRequestFormProperty> getProperties() {
return properties;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestFormProperty.java
----------------------------------------------------------------------
diff --git a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestFormProperty.java b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestFormProperty.java
index 0a431c6..95f2fec 100644
--- a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestFormProperty.java
+++ b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestFormProperty.java
@@ -51,6 +51,9 @@ public class UserRequestFormProperty extends AbstractBaseBean {
@XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
private final Map<String, String> enumValues = new HashMap<>();
+ @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
+ private final Map<String, String> dropdownValues = new HashMap<>();
+
private String value;
public String getId() {
@@ -114,6 +117,11 @@ public class UserRequestFormProperty extends AbstractBaseBean {
return enumValues;
}
+ @JsonProperty
+ public Map<String, String> getDropdownValues() {
+ return dropdownValues;
+ }
+
public String getValue() {
return value;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestTO.java
----------------------------------------------------------------------
diff --git a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestTO.java b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestTO.java
deleted file mode 100644
index d5fad6c..0000000
--- a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/to/UserRequestTO.java
+++ /dev/null
@@ -1,70 +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.to;
-
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-
-@XmlRootElement(name = "userRequest")
-@XmlType
-public class UserRequestTO extends AbstractBaseBean {
-
- private static final long serialVersionUID = -8430826310789942133L;
-
- private String processInstanceId;
-
- private String executionId;
-
- private String bpmnProcess;
-
- private String user;
-
- public String getProcessInstanceId() {
- return processInstanceId;
- }
-
- public void setProcessInstanceId(final String processInstanceId) {
- this.processInstanceId = processInstanceId;
- }
-
- public String getExecutionId() {
- return executionId;
- }
-
- public void setExecutionId(final String executionId) {
- this.executionId = executionId;
- }
-
- public String getBpmnProcess() {
- return bpmnProcess;
- }
-
- public void setBpmnProcess(final String bpmnProcess) {
- this.bpmnProcess = bpmnProcess;
- }
-
- public String getUser() {
- return user;
- }
-
- public void setUser(final String user) {
- this.user = user;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/FlowableEntitlement.java
----------------------------------------------------------------------
diff --git a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/FlowableEntitlement.java b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/FlowableEntitlement.java
index 43825a4..fbf5b02 100644
--- a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/FlowableEntitlement.java
+++ b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/FlowableEntitlement.java
@@ -36,19 +36,13 @@ public final class FlowableEntitlement {
public static final String WORKFLOW_TASK_LIST = "WORKFLOW_TASK_LIST";
- public static final String WORKFLOW_FORM_LIST = "WORKFLOW_FORM_LIST";
+ public static final String USER_REQUEST_LIST = "USER_REQUEST_LIST";
- public static final String WORKFLOW_FORM_READ = "WORKFLOW_FORM_READ";
+ public static final String USER_REQUEST_FORM_LIST = "USER_REQUEST_FORM_LIST";
- public static final String WORKFLOW_FORM_CLAIM = "WORKFLOW_FORM_CLAIM";
+ public static final String USER_REQUEST_FORM_CLAIM = "USER_REQUEST_FORM_CLAIM";
- public static final String WORKFLOW_FORM_SUBMIT = "WORKFLOW_FORM_SUBMIT";
-
- public static final String USER_REQUEST_DEF_CREATE = "USER_REQUEST_DEF_CREATE";
-
- public static final String USER_REQUEST_DEF_UPDATE = "USER_REQUEST_DEF_UPDATE";
-
- public static final String USER_REQUEST_DEF_DELETE = "USER_REQUEST_DEF_DELETE";
+ public static final String USER_REQUEST_FORM_SUBMIT = "USER_REQUEST_FORM_SUBMIT";
public static final String USER_REQUEST_START = "USER_REQUEST_START";
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/UserRequestFormPropertyType.java
----------------------------------------------------------------------
diff --git a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/UserRequestFormPropertyType.java b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/UserRequestFormPropertyType.java
index 9565f99..227296b 100644
--- a/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/UserRequestFormPropertyType.java
+++ b/ext/flowable/common-lib/src/main/java/org/apache/syncope/common/lib/types/UserRequestFormPropertyType.java
@@ -27,6 +27,7 @@ public enum UserRequestFormPropertyType {
Long,
Enum,
Date,
- Boolean
+ Boolean,
+ Dropdown
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/BpmnProcessManager.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/BpmnProcessManager.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/BpmnProcessManager.java
index 9247fd4..f7d1747 100644
--- a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/BpmnProcessManager.java
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/BpmnProcessManager.java
@@ -20,7 +20,7 @@ package org.apache.syncope.core.flowable.api;
import java.io.OutputStream;
import java.util.List;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.common.lib.types.BpmnProcessFormat;
public interface BpmnProcessManager {
@@ -28,7 +28,7 @@ public interface BpmnProcessManager {
/**
* @return all available workflow processes.
*/
- List<BpmnProcessTO> getProcesses();
+ List<BpmnProcess> getProcesses();
/**
* Export the process for the given key, in the requested format.
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/DropdownValueProvider.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/DropdownValueProvider.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/DropdownValueProvider.java
new file mode 100644
index 0000000..b6c79cf
--- /dev/null
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/DropdownValueProvider.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.core.flowable.api;
+
+import java.util.Map;
+
+/**
+ * Implementations of this interface are used with {@link org.apache.syncope.core.flowable.support.DropdownFormType}.
+ */
+public interface DropdownValueProvider {
+
+ String NAME = "dropdownValueProvider";
+
+ Map<String, String> getValues();
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/UserRequestHandler.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/UserRequestHandler.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/UserRequestHandler.java
index b11b97c..c3c6f0d 100644
--- a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/UserRequestHandler.java
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/api/UserRequestHandler.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.flowable.api;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.UserRequestTO;
+import org.apache.syncope.common.lib.to.UserRequest;
import org.apache.syncope.common.lib.to.UserRequestForm;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.entity.user.User;
@@ -33,13 +33,25 @@ import org.springframework.transaction.event.TransactionalEventListener;
public interface UserRequestHandler {
/**
+ * Get the running user requests matching the provided parameters.
+ *
+ * @param userKey user key (optional)
+ * @param page result page
+ * @param size items per page
+ * @param orderByClauses sort conditions
+ * @return total number of user requests, list of user requests matching the provided parameters
+ */
+ Pair<Integer, List<UserRequest>> getUserRequests(
+ String userKey, int page, int size, List<OrderByClause> orderByClauses);
+
+ /**
* Starts a new user request, for the given BPMN process and user.
*
* @param bpmnProcess BPMN process
* @param user user
* @return data about the started request service, including execution id
*/
- UserRequestTO start(String bpmnProcess, User user);
+ UserRequest start(String bpmnProcess, User user);
/**
* Parses the given execution id to find matching user request and owner.
@@ -73,22 +85,16 @@ public interface UserRequestHandler {
void cancelByUser(AnyDeletedEvent event);
/**
- * Get the forms for current workflow process instances matching the provided parameters.
+ * Get the forms matching the provided parameters.
*
+ * @param userKey user key (optional)
* @param page result page
* @param size items per page
* @param orderByClauses sort conditions
* @return total number of forms, list of forms matching the provided parameters
*/
- Pair<Integer, List<UserRequestForm>> getForms(int page, int size, List<OrderByClause> orderByClauses);
-
- /**
- * Get forms for given user (if present).
- *
- * @param userKey user key
- * @return form (if present), otherwise null
- */
- List<UserRequestForm> getForms(String userKey);
+ Pair<Integer, List<UserRequestForm>> getForms(
+ String userKey, int page, int size, List<OrderByClause> orderByClauses);
/**
* Claim a form for a given object.
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableBpmnProcessManager.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableBpmnProcessManager.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableBpmnProcessManager.java
index bca8b25..50b078b 100644
--- a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableBpmnProcessManager.java
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableBpmnProcessManager.java
@@ -28,9 +28,10 @@ import java.io.OutputStream;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.io.IOUtils;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.common.lib.types.BpmnProcessFormat;
import org.apache.syncope.core.flowable.support.DomainProcessEngine;
+import org.apache.syncope.core.flowable.support.DropdownAwareJsonConverter;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.workflow.api.WorkflowException;
import org.flowable.bpmn.converter.BpmnXMLConverter;
@@ -73,11 +74,11 @@ public class FlowableBpmnProcessManager implements BpmnProcessManager {
}
@Override
- public List<BpmnProcessTO> getProcesses() {
+ public List<BpmnProcess> getProcesses() {
try {
return engine.getRepositoryService().createProcessDefinitionQuery().latestVersion().list().stream().
map(procDef -> {
- BpmnProcessTO defTO = new BpmnProcessTO();
+ BpmnProcess defTO = new BpmnProcess();
defTO.setKey(procDef.getKey());
defTO.setName(procDef.getName());
@@ -163,7 +164,7 @@ public class FlowableBpmnProcessManager implements BpmnProcessManager {
"Could not find JSON node " + BpmnJsonConverter.EDITOR_CHILD_SHAPES);
}
- BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(definitionNode);
+ BpmnModel bpmnModel = new DropdownAwareJsonConverter().convertToBpmnModel(definitionNode);
deployment = FlowableDeployUtils.deployDefinition(
engine,
resourceName,
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableRuntimeUtils.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableRuntimeUtils.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableRuntimeUtils.java
index 12d8faa..cdf035d 100644
--- a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableRuntimeUtils.java
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableRuntimeUtils.java
@@ -22,6 +22,7 @@ import java.util.Base64;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.core.flowable.support.DomainProcessEngine;
@@ -33,7 +34,6 @@ import org.apache.syncope.core.workflow.api.WorkflowException;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.impl.RuntimeServiceImpl;
-import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
@@ -97,8 +97,17 @@ public final class FlowableRuntimeUtils {
return procInst == null ? null : procInst.getId();
}
- public static String getProcBusinessKey(final String processDefinitionId, final String userKey) {
- return processDefinitionId + ":" + userKey;
+ public static String getProcBusinessKey(final String procDefId, final String userKey) {
+ return procDefId + ":" + userKey;
+ }
+
+ public static Pair<String, String> splitProcBusinessKey(final String procBusinessKey) {
+ String[] split = procBusinessKey.split(":");
+ if (split == null || split.length != 2) {
+ throw new WorkflowException(new IllegalArgumentException("Unexpected business key: " + procBusinessKey));
+ }
+
+ return Pair.of(split[0], split[1]);
}
public static ProcessDefinition getLatestProcDefByKey(final DomainProcessEngine engine, final String key) {
@@ -111,17 +120,17 @@ public final class FlowableRuntimeUtils {
}
public static Set<String> getPerformedTasks(
- final DomainProcessEngine engine, final String procInstID, final User user) {
+ final DomainProcessEngine engine, final String procInstId, final User user) {
return engine.getHistoryService().createHistoricActivityInstanceQuery().
- executionId(procInstID).
+ executionId(procInstId).
list().stream().
map(HistoricActivityInstance::getActivityId).
collect(Collectors.toSet());
}
- public static void updateStatus(final DomainProcessEngine engine, final String procInstID, final User user) {
- List<Task> tasks = createTaskQuery(engine, false).processInstanceId(procInstID).list();
+ public static void updateStatus(final DomainProcessEngine engine, final String procInstId, final User user) {
+ List<Task> tasks = createTaskQuery(engine, false).processInstanceId(procInstId).list();
if (tasks.isEmpty() || tasks.size() > 1) {
LOG.warn("While setting user status: unexpected task number ({})", tasks.size());
} else {
@@ -129,13 +138,6 @@ public final class FlowableRuntimeUtils {
}
}
- public static List<ProcessInstance> getProcessInstances(final DomainProcessEngine engine, final String userKey) {
- return engine.getRuntimeService().createNativeProcessInstanceQuery().
- sql("SELECT ID_,PROC_INST_ID_ FROM " + engine.getManagementService().getTableName(ExecutionEntity.class)
- + " WHERE BUSINESS_KEY_ LIKE '" + getProcBusinessKey("%", userKey) + "'"
- + " AND PARENT_ID_ IS NULL").list();
- }
-
public static TaskQuery createTaskQuery(final DomainProcessEngine engine, final boolean onlyFormTasks) {
SyncopeTaskQueryImpl taskQuery = new SyncopeTaskQueryImpl(
((RuntimeServiceImpl) engine.getRuntimeService()).getCommandExecutor());
@@ -145,10 +147,10 @@ public final class FlowableRuntimeUtils {
return taskQuery;
}
- public static String getFormTask(final DomainProcessEngine engine, final String procInstID) {
+ public static String getFormTask(final DomainProcessEngine engine, final String procInstId) {
String result = null;
- List<Task> tasks = createTaskQuery(engine, true).processInstanceId(procInstID).list();
+ List<Task> tasks = createTaskQuery(engine, true).processInstanceId(procInstId).list();
if (tasks.isEmpty() || tasks.size() > 1) {
LOG.debug("While checking if form task: unexpected task number ({})", tasks.size());
} else {
@@ -162,7 +164,7 @@ public final class FlowableRuntimeUtils {
* Saves resources to be propagated and password for later - after form submission - propagation.
*
* @param engine Flowable engine
- * @param procInstID process instance id
+ * @param procInstId process instance id
* @param user user JPA entity
* @param userTO user transfer object
* @param password password
@@ -171,35 +173,35 @@ public final class FlowableRuntimeUtils {
*/
public static void saveForFormSubmit(
final DomainProcessEngine engine,
- final String procInstID,
+ final String procInstId,
final User user,
final UserTO userTO,
final String password,
final Boolean enabled,
final PropagationByResource propByRes) {
- String formTaskId = getFormTask(engine, procInstID);
+ String formTaskId = getFormTask(engine, procInstId);
if (formTaskId == null) {
return;
}
- engine.getRuntimeService().setVariable(procInstID, FlowableRuntimeUtils.USER_TO, userTO);
+ engine.getRuntimeService().setVariable(procInstId, FlowableRuntimeUtils.USER_TO, userTO);
if (password == null) {
String encryptedPwd = engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.ENCRYPTED_PWD, String.class);
+ getVariable(procInstId, FlowableRuntimeUtils.ENCRYPTED_PWD, String.class);
if (encryptedPwd != null) {
userTO.setPassword(decrypt(encryptedPwd));
}
} else {
userTO.setPassword(password);
engine.getRuntimeService().
- setVariable(procInstID, FlowableRuntimeUtils.ENCRYPTED_PWD, encrypt(password));
+ setVariable(procInstId, FlowableRuntimeUtils.ENCRYPTED_PWD, encrypt(password));
}
- engine.getRuntimeService().setVariable(procInstID, FlowableRuntimeUtils.ENABLED, enabled);
+ engine.getRuntimeService().setVariable(procInstId, FlowableRuntimeUtils.ENABLED, enabled);
- engine.getRuntimeService().setVariable(procInstID, FlowableRuntimeUtils.PROP_BY_RESOURCE, propByRes);
+ engine.getRuntimeService().setVariable(procInstId, FlowableRuntimeUtils.PROP_BY_RESOURCE, propByRes);
if (propByRes != null) {
propByRes.clear();
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserRequestHandler.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserRequestHandler.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserRequestHandler.java
index 1c198a8..45a834b 100644
--- a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserRequestHandler.java
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableUserRequestHandler.java
@@ -31,13 +31,14 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.patch.PasswordPatch;
import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.UserRequestTO;
+import org.apache.syncope.common.lib.to.UserRequest;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.to.UserRequestFormProperty;
import org.apache.syncope.common.lib.to.UserRequestForm;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ResourceOperation;
import org.apache.syncope.common.lib.types.UserRequestFormPropertyType;
+import org.apache.syncope.core.flowable.api.DropdownValueProvider;
import org.apache.syncope.core.flowable.api.WorkflowTaskManager;
import org.apache.syncope.core.flowable.support.DomainProcessEngine;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
@@ -49,16 +50,21 @@ import org.apache.syncope.core.provisioning.api.PropagationByResource;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
import org.apache.syncope.core.provisioning.api.event.AnyDeletedEvent;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.spring.BeanUtils;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.core.workflow.api.WorkflowException;
import org.flowable.common.engine.api.FlowableException;
+import org.flowable.common.engine.api.FlowableIllegalArgumentException;
import org.flowable.engine.form.FormProperty;
import org.flowable.engine.form.FormType;
import org.flowable.engine.form.TaskFormData;
import org.flowable.engine.history.HistoricActivityInstance;
+import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.persistence.entity.HistoricFormPropertyEntity;
+import org.flowable.engine.runtime.NativeProcessInstanceQuery;
import org.flowable.engine.runtime.ProcessInstance;
+import org.flowable.engine.runtime.ProcessInstanceQuery;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.flowable.task.api.history.HistoricTaskInstance;
@@ -93,6 +99,93 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
@Autowired
protected EntityFactory entityFactory;
+ protected NativeProcessInstanceQuery createProcessInstanceQuery(final String userKey) {
+ return engine.getRuntimeService().createNativeProcessInstanceQuery().
+ sql("SELECT DISTINCT ID_,BUSINESS_KEY_,ACT_ID_ FROM "
+ + engine.getManagementService().getTableName(ExecutionEntity.class)
+ + " WHERE BUSINESS_KEY_ LIKE '"
+ + FlowableRuntimeUtils.getProcBusinessKey("%", userKey) + "'"
+ + " AND BUSINESS_KEY_ NOT LIKE '"
+ + FlowableRuntimeUtils.getProcBusinessKey(FlowableRuntimeUtils.WF_PROCESS_ID, "%") + "'"
+ + " AND PARENT_ID_ IS NULL");
+ }
+
+ protected int countProcessInstances(final String userKey) {
+ return (int) engine.getRuntimeService().createNativeProcessInstanceQuery().
+ sql("SELECT COUNT(ID_) FROM "
+ + engine.getManagementService().getTableName(ExecutionEntity.class)
+ + " WHERE BUSINESS_KEY_ LIKE '"
+ + FlowableRuntimeUtils.getProcBusinessKey("%", userKey) + "'"
+ + " AND BUSINESS_KEY_ NOT LIKE '"
+ + FlowableRuntimeUtils.getProcBusinessKey(FlowableRuntimeUtils.WF_PROCESS_ID, "%") + "'"
+ + " AND PARENT_ID_ IS NULL").count();
+ }
+
+ protected UserRequest getUserRequest(final ProcessInstance procInst) {
+ Pair<String, String> split = FlowableRuntimeUtils.splitProcBusinessKey(procInst.getBusinessKey());
+
+ UserRequest userRequest = new UserRequest();
+ userRequest.setBpmnProcess(split.getLeft());
+ userRequest.setUser(split.getRight());
+ userRequest.setExecutionId(procInst.getId());
+ userRequest.setActivityId(procInst.getActivityId());
+ return userRequest;
+ }
+
+ @Transactional(readOnly = true)
+ @Override
+ public Pair<Integer, List<UserRequest>> getUserRequests(
+ final String userKey,
+ final int page,
+ final int size,
+ final List<OrderByClause> orderByClauses) {
+
+ Integer count = null;
+ List<UserRequest> result = null;
+ if (userKey == null) {
+ ProcessInstanceQuery query = engine.getRuntimeService().createProcessInstanceQuery().active();
+ for (OrderByClause clause : orderByClauses) {
+ boolean sorted = true;
+ switch (clause.getField().trim()) {
+ case "processDefinitionId":
+ query.orderByProcessDefinitionId();
+ break;
+
+ case "processDefinitionKey":
+ query.orderByProcessDefinitionKey();
+ break;
+
+ case "processInstanceId":
+ query.orderByProcessInstanceId();
+ break;
+
+ default:
+ LOG.warn("User request sort request by {}: unsupported, ignoring", clause.getField().trim());
+ sorted = false;
+ }
+ if (sorted) {
+ if (clause.getDirection() == OrderByClause.Direction.ASC) {
+ query.asc();
+ } else {
+ query.desc();
+ }
+ }
+
+ count = (int) query.count();
+ result = query.listPage(size * (page <= 0 ? 0 : page - 1), size).stream().
+ map(procInst -> getUserRequest(procInst)).
+ collect(Collectors.toList());
+ }
+ } else {
+ count = countProcessInstances(userKey);
+ result = createProcessInstanceQuery(userKey).listPage(size * (page <= 0 ? 0 : page - 1), size).stream().
+ map(procInst -> getUserRequest(procInst)).
+ collect(Collectors.toList());
+ }
+
+ return Pair.of(count, result);
+ }
+
protected User lazyLoad(final User user) {
// 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
@@ -101,8 +194,8 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
}
@Override
- public UserRequestTO start(final String bpmnProcess, final User user) {
- Map<String, Object> variables = new HashMap<>(2);
+ public UserRequest start(final String bpmnProcess, final User user) {
+ Map<String, Object> variables = new HashMap<>();
variables.put(FlowableRuntimeUtils.WF_EXECUTOR, AuthContextUtils.getUsername());
variables.put(FlowableRuntimeUtils.USER, lazyLoad(user));
variables.put(FlowableRuntimeUtils.USER_TO, dataBinder.getUserTO(user, true));
@@ -118,12 +211,8 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
procInst.getProcessInstanceId(),
FlowableRuntimeUtils.getProcBusinessKey(bpmnProcess, user.getKey()));
- UserRequestTO userRequestTO = new UserRequestTO();
- userRequestTO.setProcessInstanceId(procInst.getProcessInstanceId());
- userRequestTO.setExecutionId(procInst.getId());
- userRequestTO.setBpmnProcess(bpmnProcess);
- userRequestTO.setUser(user.getKey());
- return userRequestTO;
+ return getUserRequest(engine.getRuntimeService().createProcessInstanceQuery().
+ processInstanceId(procInst.getProcessInstanceId()).singleResult());
}
@Override
@@ -132,7 +221,11 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
try {
procInst = engine.getRuntimeService().
createProcessInstanceQuery().processInstanceId(executionId).singleResult();
+ if (procInst == null) {
+ throw new FlowableIllegalArgumentException("ProcessInstance with id " + executionId);
+ }
} catch (FlowableException e) {
+ LOG.error("Could find execution ProcessInstance with id {}", executionId, e);
throw new NotFoundException("User request execution with id " + executionId);
}
@@ -163,7 +256,7 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
public void cancelByUser(final AnyDeletedEvent event) {
if (AuthContextUtils.getDomain().equals(event.getDomain()) && event.getAnyTypeKind() == AnyTypeKind.USER) {
String username = event.getAnyName();
- FlowableRuntimeUtils.getProcessInstances(engine, event.getAnyKey()).
+ createProcessInstanceQuery(event.getAnyKey()).list().
forEach(procInst -> {
engine.getRuntimeService().deleteProcessInstance(
procInst.getId(), "Cascade Delete user " + username);
@@ -192,6 +285,10 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
result = UserRequestFormPropertyType.Boolean;
break;
+ case "dropdown":
+ result = UserRequestFormPropertyType.Dropdown;
+ break;
+
case "string":
default:
break;
@@ -201,19 +298,19 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
return result;
}
- protected UserRequestForm getFormTO(final Task task) {
- return getFormTO(task, engine.getFormService().getTaskFormData(task.getId()));
+ protected UserRequestForm getForm(final Task task) {
+ return FlowableUserRequestHandler.this.getForm(task, engine.getFormService().getTaskFormData(task.getId()));
}
- protected UserRequestForm getFormTO(final Task task, final TaskFormData fd) {
+ protected UserRequestForm getForm(final Task task, final TaskFormData fd) {
UserRequestForm formTO =
- getFormTO(task.getProcessInstanceId(), task.getId(), fd.getFormKey(), fd.getFormProperties());
+ getForm(task.getProcessInstanceId(), task.getId(), fd.getFormKey(), fd.getFormProperties());
BeanUtils.copyProperties(task, formTO);
return formTO;
}
- protected UserRequestForm getFormTO(final HistoricTaskInstance task) {
+ protected UserRequestForm getForm(final HistoricTaskInstance task) {
List<HistoricFormPropertyEntity> props = engine.getHistoryService().
createHistoricDetailQuery().taskId(task.getId()).list().stream().
filter(HistoricFormPropertyEntity.class::isInstance).
@@ -244,16 +341,19 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
}
protected UserRequestForm getHistoricFormTO(
- final String procInstID,
+ final String procInstId,
final String taskId,
final String formKey,
final List<HistoricFormPropertyEntity> props) {
UserRequestForm formTO = new UserRequestForm();
- User user = userDAO.find(getUserKey(procInstID));
+ formTO.setBpmnProcess(engine.getRuntimeService().createProcessInstanceQuery().
+ processInstanceId(procInstId).singleResult().getProcessDefinitionKey());
+
+ User user = userDAO.find(getUserKey(procInstId));
if (user == null) {
- throw new NotFoundException("User for process instance id " + procInstID);
+ throw new NotFoundException("User for process instance id " + procInstId);
}
formTO.setUsername(user.getUsername());
@@ -261,9 +361,9 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
formTO.setFormKey(formKey);
formTO.setUserTO(engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.USER_TO, UserTO.class));
+ getVariable(procInstId, FlowableRuntimeUtils.USER_TO, UserTO.class));
formTO.setUserPatch(engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.USER_PATCH, UserPatch.class));
+ getVariable(procInstId, FlowableRuntimeUtils.USER_PATCH, UserPatch.class));
formTO.getProperties().addAll(props.stream().map(prop -> {
UserRequestFormProperty propertyTO = new UserRequestFormProperty();
@@ -277,37 +377,58 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
}
@SuppressWarnings("unchecked")
- protected UserRequestForm getFormTO(
- final String procInstID,
+ protected UserRequestForm getForm(
+ final String procInstId,
final String taskId,
final String formKey,
final List<FormProperty> props) {
UserRequestForm formTO = new UserRequestForm();
- User user = userDAO.find(getUserKey(procInstID));
+ formTO.setBpmnProcess(engine.getRuntimeService().createProcessInstanceQuery().
+ processInstanceId(procInstId).singleResult().getProcessDefinitionKey());
+
+ User user = userDAO.find(getUserKey(procInstId));
if (user == null) {
- throw new NotFoundException("User for process instance id " + procInstID);
+ throw new NotFoundException("User for process instance id " + procInstId);
}
formTO.setUsername(user.getUsername());
+ formTO.setExecutionId(procInstId);
formTO.setTaskId(taskId);
formTO.setFormKey(formKey);
formTO.setUserTO(engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.USER_TO, UserTO.class));
+ getVariable(procInstId, FlowableRuntimeUtils.USER_TO, UserTO.class));
formTO.setUserPatch(engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.USER_PATCH, UserPatch.class));
+ getVariable(procInstId, FlowableRuntimeUtils.USER_PATCH, UserPatch.class));
formTO.getProperties().addAll(props.stream().map(fProp -> {
UserRequestFormProperty propertyTO = new UserRequestFormProperty();
BeanUtils.copyProperties(fProp, propertyTO, PROPERTY_IGNORE_PROPS);
propertyTO.setType(fromFlowableFormType(fProp.getType()));
- if (propertyTO.getType() == UserRequestFormPropertyType.Date) {
- propertyTO.setDatePattern((String) fProp.getType().getInformation("datePattern"));
- }
- if (propertyTO.getType() == UserRequestFormPropertyType.Enum) {
- propertyTO.getEnumValues().putAll((Map<String, String>) fProp.getType().getInformation("values"));
+ switch (propertyTO.getType()) {
+ case Date:
+ propertyTO.setDatePattern((String) fProp.getType().getInformation("datePattern"));
+ break;
+
+ case Enum:
+ propertyTO.getEnumValues().putAll((Map<String, String>) fProp.getType().getInformation("values"));
+ break;
+
+ case Dropdown:
+ String valueProviderBean = (String) fProp.getType().getInformation(DropdownValueProvider.NAME);
+ try {
+ DropdownValueProvider valueProvider = ApplicationContextProvider.getApplicationContext().
+ getBean(valueProviderBean, DropdownValueProvider.class);
+ propertyTO.getDropdownValues().putAll(valueProvider.getValues());
+ } catch (Exception e) {
+ LOG.error("Could not find bean {} of type {} for form property {}",
+ valueProviderBean, DropdownValueProvider.class.getName(), propertyTO.getId(), e);
+ }
+ break;
+
+ default:
}
return propertyTO;
}).collect(Collectors.toList()));
@@ -318,26 +439,28 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
@Transactional(readOnly = true)
@Override
public Pair<Integer, List<UserRequestForm>> getForms(
- final int page, final int size, final List<OrderByClause> orderByClauses) {
+ final String userKey,
+ final int page,
+ final int size,
+ final List<OrderByClause> orderByClauses) {
- Pair<Integer, List<UserRequestForm>> forms = null;
+ Pair<Integer, List<UserRequestForm>> forms;
- TaskQuery formTaskQuery = FlowableRuntimeUtils.createTaskQuery(engine, true);
+ TaskQuery query = FlowableRuntimeUtils.createTaskQuery(engine, true);
+ if (userKey != null) {
+ query.processInstanceBusinessKeyLike(FlowableRuntimeUtils.getProcBusinessKey("%", userKey));
+ }
String authUser = AuthContextUtils.getUsername();
if (adminUser.equals(authUser)) {
- forms = getForms(formTaskQuery, page, size, orderByClauses);
+ forms = getForms(query, page, size, orderByClauses);
} else {
User user = userDAO.findByUsername(authUser);
- if (user == null) {
- throw new NotFoundException("Syncope User " + authUser);
- }
-
- forms = getForms(formTaskQuery.taskCandidateOrAssigned(user.getUsername()), page, size, orderByClauses);
+ forms = getForms(query.taskCandidateOrAssigned(user.getUsername()), page, size, orderByClauses);
List<String> candidateGroups = new ArrayList<>(userDAO.findAllGroupNames(user));
if (!candidateGroups.isEmpty()) {
- forms = getForms(formTaskQuery.taskCandidateGroupIn(candidateGroups), page, size, orderByClauses);
+ forms = getForms(query.taskCandidateGroupIn(candidateGroups), page, size, orderByClauses);
}
}
@@ -349,75 +472,56 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
protected Pair<Integer, List<UserRequestForm>> getForms(
final TaskQuery query, final int page, final int size, final List<OrderByClause> orderByClauses) {
- TaskQuery sortedQuery = query;
for (OrderByClause clause : orderByClauses) {
- boolean ack = true;
+ boolean sorted = true;
switch (clause.getField().trim()) {
+ case "bpmnProcess":
+ query.orderByProcessDefinitionId();
+ break;
+
+ case "executionId":
+ query.orderByExecutionId();
+ break;
+
case "taskId":
- sortedQuery = sortedQuery.orderByTaskId();
+ query.orderByTaskId();
break;
case "createTime":
- sortedQuery = sortedQuery.orderByTaskCreateTime();
+ query.orderByTaskCreateTime();
break;
case "dueDate":
- sortedQuery = sortedQuery.orderByTaskDueDate();
+ query.orderByTaskDueDate();
break;
case "owner":
- sortedQuery = sortedQuery.orderByTaskOwner();
+ query.orderByTaskOwner();
break;
default:
LOG.warn("Form sort request by {}: unsupported, ignoring", clause.getField().trim());
- ack = false;
+ sorted = false;
}
- if (ack) {
- sortedQuery = clause.getDirection() == OrderByClause.Direction.ASC
- ? sortedQuery.asc()
- : sortedQuery.desc();
+ if (sorted) {
+ if (clause.getDirection() == OrderByClause.Direction.ASC) {
+ query.asc();
+ } else {
+ query.desc();
+ }
}
}
- List<UserRequestForm> result = sortedQuery.listPage(size * (page <= 0 ? 0 : page - 1), size).stream().
+ List<UserRequestForm> result = query.listPage(size * (page <= 0 ? 0 : page - 1), size).stream().
map(task -> task instanceof HistoricTaskInstance
- ? getFormTO((HistoricTaskInstance) task) : getFormTO(task)).
+ ? FlowableUserRequestHandler.this.getForm((HistoricTaskInstance) task)
+ : FlowableUserRequestHandler.this.getForm(task)).
collect(Collectors.toList());
return Pair.of((int) query.count(), result);
}
- @Override
- public List<UserRequestForm> getForms(final String userKey) {
- List<UserRequestForm> result = new ArrayList<>();
- FlowableRuntimeUtils.getProcessInstances(engine, userKey).forEach(procInst -> {
- Task task;
- try {
- task = FlowableRuntimeUtils.createTaskQuery(engine, true).
- processInstanceId(procInst.getProcessInstanceId()).singleResult();
- } catch (FlowableException e) {
- throw new WorkflowException("While reading form for process instance "
- + procInst.getProcessInstanceId(), e);
- }
-
- if (task != null) {
- TaskFormData formData;
- try {
- formData = engine.getFormService().getTaskFormData(task.getId());
- } catch (FlowableException e) {
- throw new WorkflowException("Error while getting form data for task " + task.getId(), e);
- }
- if (formData != null && !formData.getFormProperties().isEmpty()) {
- result.add(getFormTO(task, formData));
- }
- }
- });
-
- return result;
- }
-
- protected Pair<Task, TaskFormData> checkTask(final String taskId, final String authUser) {
+ protected Pair<Task, TaskFormData> parseTask(final String taskId) {
Task task;
try {
task = FlowableRuntimeUtils.createTaskQuery(engine, true).taskId(taskId).singleResult();
@@ -435,27 +539,20 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
throw new NotFoundException("Form for Flowable Task " + taskId, e);
}
- if (!adminUser.equals(authUser)) {
- User user = userDAO.findByUsername(authUser);
- if (user == null) {
- throw new NotFoundException("Syncope User " + authUser);
- }
- }
-
return Pair.of(task, formData);
}
@Override
public UserRequestForm claimForm(final String taskId) {
- String authUser = AuthContextUtils.getUsername();
- Pair<Task, TaskFormData> checked = checkTask(taskId, authUser);
+ Pair<Task, TaskFormData> parsed = parseTask(taskId);
+ String authUser = AuthContextUtils.getUsername();
if (!adminUser.equals(authUser)) {
List<Task> tasksForUser = FlowableRuntimeUtils.createTaskQuery(engine, true).
- taskId(taskId).taskCandidateUser(authUser).list();
+ taskId(taskId).taskCandidateOrAssigned(authUser).list();
if (tasksForUser.isEmpty()) {
throw new WorkflowException(
- new IllegalArgumentException(authUser + " is not candidate for task " + taskId));
+ new IllegalArgumentException(authUser + " is not candidate nor assignee of task " + taskId));
}
}
@@ -467,7 +564,7 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
throw new WorkflowException("While reading task " + taskId, e);
}
- return getFormTO(task, checked.getRight());
+ return FlowableUserRequestHandler.this.getForm(task, parsed.getRight());
}
private Map<String, String> getPropertiesForSubmit(final UserRequestForm form) {
@@ -482,36 +579,36 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
@Override
public WorkflowResult<UserPatch> submitForm(final UserRequestForm form) {
- String authUser = AuthContextUtils.getUsername();
- Pair<Task, TaskFormData> checked = checkTask(form.getTaskId(), authUser);
+ Pair<Task, TaskFormData> parsed = parseTask(form.getTaskId());
- if (!checked.getLeft().getOwner().equals(authUser)) {
+ String authUser = AuthContextUtils.getUsername();
+ if (!parsed.getLeft().getOwner().equals(authUser)) {
throw new WorkflowException(new IllegalArgumentException("Task " + form.getTaskId() + " assigned to "
- + checked.getLeft().getOwner() + " but submitted by " + authUser));
+ + parsed.getLeft().getOwner() + " but submitted by " + authUser));
}
- String procInstID = checked.getLeft().getProcessInstanceId();
+ String procInstId = parsed.getLeft().getProcessInstanceId();
- User user = userDAO.find(getUserKey(procInstID));
+ User user = userDAO.find(getUserKey(procInstId));
if (user == null) {
- throw new NotFoundException("User with key " + getUserKey(procInstID));
+ throw new NotFoundException("User with key " + getUserKey(procInstId));
}
- Set<String> preTasks = FlowableRuntimeUtils.getPerformedTasks(engine, procInstID, user);
+ Set<String> preTasks = FlowableRuntimeUtils.getPerformedTasks(engine, procInstId, user);
- engine.getRuntimeService().setVariable(procInstID, FlowableRuntimeUtils.TASK, "submit");
- engine.getRuntimeService().setVariable(procInstID, FlowableRuntimeUtils.FORM_SUBMITTER, authUser);
- engine.getRuntimeService().setVariable(procInstID, FlowableRuntimeUtils.USER, lazyLoad(user));
+ engine.getRuntimeService().setVariable(procInstId, FlowableRuntimeUtils.TASK, "submit");
+ engine.getRuntimeService().setVariable(procInstId, FlowableRuntimeUtils.FORM_SUBMITTER, authUser);
+ engine.getRuntimeService().setVariable(procInstId, FlowableRuntimeUtils.USER, lazyLoad(user));
try {
engine.getFormService().submitTaskFormData(form.getTaskId(), getPropertiesForSubmit(form));
} catch (FlowableException e) {
FlowableRuntimeUtils.throwException(e, "While submitting form for task " + form.getTaskId());
}
- Set<String> postTasks = FlowableRuntimeUtils.getPerformedTasks(engine, procInstID, user);
+ Set<String> postTasks = FlowableRuntimeUtils.getPerformedTasks(engine, procInstId, user);
postTasks.removeAll(preTasks);
postTasks.add(form.getTaskId());
- if (procInstID.equals(FlowableRuntimeUtils.getWFProcInstID(engine, user.getKey()))) {
- FlowableRuntimeUtils.updateStatus(engine, procInstID, user);
+ if (procInstId.equals(FlowableRuntimeUtils.getWFProcInstID(engine, user.getKey()))) {
+ FlowableRuntimeUtils.updateStatus(engine, procInstId, user);
}
user = userDAO.save(user);
@@ -521,34 +618,34 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
PropagationByResource propByRes = null;
ProcessInstance afterSubmitPI = engine.getRuntimeService().
- createProcessInstanceQuery().processInstanceId(procInstID).singleResult();
+ createProcessInstanceQuery().processInstanceId(procInstId).singleResult();
if (afterSubmitPI != null) {
- engine.getRuntimeService().removeVariable(procInstID, FlowableRuntimeUtils.TASK);
- engine.getRuntimeService().removeVariable(procInstID, FlowableRuntimeUtils.FORM_SUBMITTER);
- engine.getRuntimeService().removeVariable(procInstID, FlowableRuntimeUtils.USER);
- engine.getRuntimeService().removeVariable(procInstID, FlowableRuntimeUtils.USER_TO);
+ engine.getRuntimeService().removeVariable(procInstId, FlowableRuntimeUtils.TASK);
+ engine.getRuntimeService().removeVariable(procInstId, FlowableRuntimeUtils.FORM_SUBMITTER);
+ engine.getRuntimeService().removeVariable(procInstId, FlowableRuntimeUtils.USER);
+ engine.getRuntimeService().removeVariable(procInstId, FlowableRuntimeUtils.USER_TO);
// see if there is any propagation to be done
propByRes = engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.PROP_BY_RESOURCE, PropagationByResource.class);
- engine.getRuntimeService().removeVariable(procInstID, FlowableRuntimeUtils.PROP_BY_RESOURCE);
+ getVariable(procInstId, FlowableRuntimeUtils.PROP_BY_RESOURCE, PropagationByResource.class);
+ engine.getRuntimeService().removeVariable(procInstId, FlowableRuntimeUtils.PROP_BY_RESOURCE);
// fetch - if available - the encrypted password
String encryptedPwd = engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.ENCRYPTED_PWD, String.class);
- engine.getRuntimeService().removeVariable(procInstID, FlowableRuntimeUtils.ENCRYPTED_PWD);
+ getVariable(procInstId, FlowableRuntimeUtils.ENCRYPTED_PWD, String.class);
+ engine.getRuntimeService().removeVariable(procInstId, FlowableRuntimeUtils.ENCRYPTED_PWD);
if (StringUtils.isNotBlank(encryptedPwd)) {
clearPassword = FlowableRuntimeUtils.decrypt(encryptedPwd);
}
Boolean enabled = engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.ENABLED, Boolean.class);
- engine.getRuntimeService().removeVariable(procInstID, FlowableRuntimeUtils.ENABLED);
+ getVariable(procInstId, FlowableRuntimeUtils.ENABLED, Boolean.class);
+ engine.getRuntimeService().removeVariable(procInstId, FlowableRuntimeUtils.ENABLED);
// supports approval chains
FlowableRuntimeUtils.saveForFormSubmit(
engine,
- procInstID,
+ procInstId,
user,
dataBinder.getUserTO(user, true),
clearPassword,
@@ -556,8 +653,8 @@ public class FlowableUserRequestHandler implements UserRequestHandler {
propByRes);
userPatch = engine.getRuntimeService().
- getVariable(procInstID, FlowableRuntimeUtils.USER_PATCH, UserPatch.class);
- engine.getRuntimeService().removeVariable(procInstID, FlowableRuntimeUtils.USER_PATCH);
+ getVariable(procInstId, FlowableRuntimeUtils.USER_PATCH, UserPatch.class);
+ engine.getRuntimeService().removeVariable(procInstId, FlowableRuntimeUtils.USER_PATCH);
}
if (userPatch == null) {
userPatch = new UserPatch();
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DomainProcessEngineFactoryBean.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DomainProcessEngineFactoryBean.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DomainProcessEngineFactoryBean.java
index 162b113..de2bbfe 100644
--- a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DomainProcessEngineFactoryBean.java
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DomainProcessEngineFactoryBean.java
@@ -18,13 +18,16 @@
*/
package org.apache.syncope.core.flowable.support;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.ProcessEngine;
import org.flowable.common.engine.impl.cfg.SpringBeanFactoryProxyMap;
import org.flowable.common.engine.impl.interceptor.EngineConfigurationConstants;
+import org.flowable.engine.form.AbstractFormType;
import org.flowable.engine.impl.util.EngineServiceUtil;
import org.flowable.idm.spring.SpringIdmEngineConfiguration;
import org.flowable.spring.SpringExpressionManager;
@@ -81,6 +84,9 @@ public class DomainProcessEngineFactoryBean
EngineConfigurationConstants.KEY_IDM_ENGINE_CONFIG,
ctx.getBean(SpringIdmEngineConfiguration.class));
}
+ List<AbstractFormType> customFormTypes = new ArrayList<>();
+ customFormTypes.add(new DropdownFormType(null));
+ conf.setCustomFormTypes(customFormTypes);
engines.put(domain, conf.buildProcessEngine());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownAwareJsonConverter.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownAwareJsonConverter.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownAwareJsonConverter.java
new file mode 100644
index 0000000..ad29e17
--- /dev/null
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownAwareJsonConverter.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.core.flowable.support;
+
+import org.flowable.bpmn.model.UserTask;
+import org.flowable.editor.constants.StencilConstants;
+import org.flowable.editor.language.json.converter.BpmnJsonConverter;
+
+public class DropdownAwareJsonConverter extends BpmnJsonConverter {
+
+ public DropdownAwareJsonConverter() {
+ convertersToBpmnMap.put(StencilConstants.STENCIL_TASK_USER, DropdownAwareUserTaskJsonConverter.class);
+ convertersToJsonMap.put(UserTask.class, DropdownAwareUserTaskJsonConverter.class);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownAwareUserTaskJsonConverter.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownAwareUserTaskJsonConverter.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownAwareUserTaskJsonConverter.java
new file mode 100644
index 0000000..838201c
--- /dev/null
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownAwareUserTaskJsonConverter.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.flowable.support;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.flowable.bpmn.model.BaseElement;
+import org.flowable.bpmn.model.FormProperty;
+import org.flowable.bpmn.model.FormValue;
+import org.flowable.bpmn.model.StartEvent;
+import org.flowable.bpmn.model.UserTask;
+import org.flowable.editor.language.json.converter.BpmnJsonConverterUtil;
+import org.flowable.editor.language.json.converter.UserTaskJsonConverter;
+
+public class DropdownAwareUserTaskJsonConverter extends UserTaskJsonConverter {
+
+ @Override
+ protected void convertJsonToFormProperties(final JsonNode objectNode, final BaseElement element) {
+ JsonNode formPropertiesNode = getProperty(PROPERTY_FORM_PROPERTIES, objectNode);
+ if (formPropertiesNode != null) {
+ formPropertiesNode = BpmnJsonConverterUtil.validateIfNodeIsTextual(formPropertiesNode);
+ JsonNode propertiesArray = formPropertiesNode.get("formProperties");
+ if (propertiesArray != null) {
+ for (JsonNode formNode : propertiesArray) {
+ JsonNode formIdNode = formNode.get(PROPERTY_FORM_ID);
+ if (formIdNode != null && StringUtils.isNotEmpty(formIdNode.asText())) {
+
+ FormProperty formProperty = new FormProperty();
+ formProperty.setId(formIdNode.asText());
+ formProperty.setName(getValueAsString(PROPERTY_FORM_NAME, formNode));
+ formProperty.setType(getValueAsString(PROPERTY_FORM_TYPE, formNode));
+ formProperty.setExpression(getValueAsString(PROPERTY_FORM_EXPRESSION, formNode));
+ formProperty.setVariable(getValueAsString(PROPERTY_FORM_VARIABLE, formNode));
+
+ if ("date".equalsIgnoreCase(formProperty.getType())) {
+ formProperty.setDatePattern(getValueAsString(PROPERTY_FORM_DATE_PATTERN, formNode));
+
+ } else if ("enum".equalsIgnoreCase(formProperty.getType())
+ || "dropdown".equalsIgnoreCase(formProperty.getType())) {
+
+ JsonNode enumValuesNode = formNode.get(PROPERTY_FORM_ENUM_VALUES);
+ if (enumValuesNode != null) {
+ List<FormValue> formValueList = new ArrayList<>();
+ for (JsonNode enumNode : enumValuesNode) {
+ if (enumNode.get(PROPERTY_FORM_ENUM_VALUES_ID) != null && !enumNode.get(
+ PROPERTY_FORM_ENUM_VALUES_ID).isNull() && enumNode.get(
+ PROPERTY_FORM_ENUM_VALUES_NAME) != null
+ && !enumNode.get(PROPERTY_FORM_ENUM_VALUES_NAME).isNull()) {
+
+ FormValue formValue = new FormValue();
+ formValue.setId(enumNode.get(PROPERTY_FORM_ENUM_VALUES_ID).asText());
+ formValue.setName(enumNode.get(PROPERTY_FORM_ENUM_VALUES_NAME).asText());
+ formValueList.add(formValue);
+
+ } else if (enumNode.get("value") != null && !enumNode.get("value").isNull()) {
+ FormValue formValue = new FormValue();
+ formValue.setId(enumNode.get("value").asText());
+ formValue.setName(enumNode.get("value").asText());
+ formValueList.add(formValue);
+ }
+ }
+ formProperty.setFormValues(formValueList);
+ }
+ }
+
+ formProperty.setRequired(getValueAsBoolean(PROPERTY_FORM_REQUIRED, formNode));
+ formProperty.setReadable(getValueAsBoolean(PROPERTY_FORM_READABLE, formNode));
+ formProperty.setWriteable(getValueAsBoolean(PROPERTY_FORM_WRITABLE, formNode));
+
+ if (element instanceof StartEvent) {
+ ((StartEvent) element).getFormProperties().add(formProperty);
+ } else if (element instanceof UserTask) {
+ ((UserTask) element).getFormProperties().add(formProperty);
+ }
+ }
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownFormType.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownFormType.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownFormType.java
new file mode 100644
index 0000000..6c612f6
--- /dev/null
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DropdownFormType.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.flowable.support;
+
+import org.flowable.engine.form.AbstractFormType;
+
+/**
+ * Extension to predefined Flowable form types relying on the provided
+ * {@link org.apache.syncope.core.flowable.api.DropdownValueProvider} bean to populate values.
+ */
+public class DropdownFormType extends AbstractFormType {
+
+ private static final long serialVersionUID = -3549337216346168946L;
+
+ protected final String dropdownValueProvider;
+
+ public DropdownFormType(final String dropdownValueProvider) {
+ this.dropdownValueProvider = dropdownValueProvider;
+ }
+
+ @Override
+ public String getName() {
+ return "dropdown";
+ }
+
+ @Override
+ public Object getInformation(final String key) {
+ if (key.equals("dropdownValueProvider")) {
+ return dropdownValueProvider;
+ }
+ return null;
+ }
+
+ @Override
+ public Object convertFormValueToModelValue(final String propertyValue) {
+ return propertyValue;
+ }
+
+ @Override
+ public String convertModelValueToFormValue(final Object modelValue) {
+ return modelValue == null ? null : modelValue.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/SyncopeFormHandlerHelper.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/SyncopeFormHandlerHelper.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/SyncopeFormHandlerHelper.java
new file mode 100644
index 0000000..9f6e751
--- /dev/null
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/SyncopeFormHandlerHelper.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.flowable.support;
+
+import org.flowable.bpmn.model.FlowElement;
+import org.flowable.bpmn.model.UserTask;
+import org.flowable.bpmn.model.Process;
+import org.flowable.engine.impl.form.FormHandlerHelper;
+import org.flowable.engine.impl.form.TaskFormHandler;
+import org.flowable.engine.impl.persistence.entity.DeploymentEntity;
+import org.flowable.engine.impl.util.CommandContextUtil;
+import org.flowable.engine.impl.util.ProcessDefinitionUtil;
+import org.flowable.engine.repository.ProcessDefinition;
+
+/**
+ * Used to inject {@link SyncopeTaskFormHandler} rather than
+ * {@link org.flowable.engine.impl.form.DefaultTaskFormHandler}.
+ */
+public class SyncopeFormHandlerHelper extends FormHandlerHelper {
+
+ @Override
+ public TaskFormHandler getTaskFormHandlder(final String procDefId, final String taskId) {
+ Process process = ProcessDefinitionUtil.getProcess(procDefId);
+ FlowElement flowElement = process.getFlowElement(taskId, true);
+ if (flowElement instanceof UserTask) {
+ UserTask userTask = (UserTask) flowElement;
+
+ ProcessDefinition processDefinitionEntity = ProcessDefinitionUtil.getProcessDefinition(procDefId);
+ DeploymentEntity deploymentEntity = CommandContextUtil.getProcessEngineConfiguration().
+ getDeploymentEntityManager().findById(processDefinitionEntity.getDeploymentId());
+
+ TaskFormHandler taskFormHandler = new SyncopeTaskFormHandler();
+ taskFormHandler.parseConfiguration(
+ userTask.getFormProperties(), userTask.getFormKey(), deploymentEntity, processDefinitionEntity);
+ return taskFormHandler;
+ }
+
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/SyncopeTaskFormHandler.java
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/SyncopeTaskFormHandler.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/SyncopeTaskFormHandler.java
new file mode 100644
index 0000000..69c5e50
--- /dev/null
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/SyncopeTaskFormHandler.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.flowable.support;
+
+import java.util.List;
+import java.util.Optional;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.core.flowable.api.DropdownValueProvider;
+import org.flowable.bpmn.model.FormProperty;
+import org.flowable.common.engine.api.delegate.Expression;
+import org.flowable.common.engine.impl.el.ExpressionManager;
+import org.flowable.engine.form.AbstractFormType;
+import org.flowable.engine.impl.form.DefaultTaskFormHandler;
+import org.flowable.engine.impl.form.FormPropertyHandler;
+import org.flowable.engine.impl.form.FormTypes;
+import org.flowable.engine.impl.persistence.entity.DeploymentEntity;
+import org.flowable.engine.impl.util.CommandContextUtil;
+import org.flowable.engine.repository.ProcessDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Extends {@link DefaultTaskFormHandler} with purpose of supporting more form types than Flowable's default.
+ */
+public class SyncopeTaskFormHandler extends DefaultTaskFormHandler {
+
+ private static final long serialVersionUID = -5271243544388455797L;
+
+ protected static final Logger LOG = LoggerFactory.getLogger(SyncopeTaskFormHandler.class);
+
+ protected Optional<AbstractFormType> parseFormPropertyType(
+ final FormProperty formProperty, final ExpressionManager expressionManager) {
+
+ AbstractFormType formType = null;
+
+ switch (formProperty.getType()) {
+ case "dropdown":
+ if (formProperty.getFormValues().isEmpty()
+ || !DropdownValueProvider.NAME.equals(formProperty.getFormValues().get(0).getId())) {
+
+ LOG.warn("A single value with id '" + DropdownValueProvider.NAME + "' was expected, ignoring");
+ } else {
+ formType = new DropdownFormType(formProperty.getFormValues().get(0).getName());
+ }
+ break;
+
+ default:
+ }
+
+ return Optional.ofNullable(formType);
+ }
+
+ @Override
+ public void parseConfiguration(
+ final List<FormProperty> formProperties,
+ final String formKey,
+ final DeploymentEntity deployment,
+ final ProcessDefinition processDefinition) {
+
+ this.deploymentId = deployment.getId();
+
+ ExpressionManager expressionManager = CommandContextUtil.getProcessEngineConfiguration().getExpressionManager();
+
+ if (StringUtils.isNotEmpty(formKey)) {
+ this.formKey = expressionManager.createExpression(formKey);
+ }
+
+ FormTypes formTypes = CommandContextUtil.getProcessEngineConfiguration().getFormTypes();
+
+ formProperties.forEach(formProperty -> {
+ FormPropertyHandler formPropertyHandler = new FormPropertyHandler();
+ formPropertyHandler.setId(formProperty.getId());
+ formPropertyHandler.setName(formProperty.getName());
+
+ AbstractFormType type = parseFormPropertyType(formProperty, expressionManager).
+ orElse(formTypes.parseFormPropertyType(formProperty));
+ formPropertyHandler.setType(type);
+ formPropertyHandler.setRequired(formProperty.isRequired());
+ formPropertyHandler.setReadable(formProperty.isReadable());
+ formPropertyHandler.setWritable(formProperty.isWriteable());
+ formPropertyHandler.setVariableName(formProperty.getVariable());
+
+ if (StringUtils.isNotEmpty(formProperty.getExpression())) {
+ Expression expression = expressionManager.createExpression(formProperty.getExpression());
+ formPropertyHandler.setVariableExpression(expression);
+ }
+
+ if (StringUtils.isNotEmpty(formProperty.getDefaultExpression())) {
+ Expression defaultExpression = expressionManager.createExpression(formProperty.getDefaultExpression());
+ formPropertyHandler.setDefaultExpression(defaultExpression);
+ }
+
+ formPropertyHandlers.add(formPropertyHandler);
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/flowable-bpmn/src/main/resources/workflowFlowableContext.xml
----------------------------------------------------------------------
diff --git a/ext/flowable/flowable-bpmn/src/main/resources/workflowFlowableContext.xml b/ext/flowable/flowable-bpmn/src/main/resources/workflowFlowableContext.xml
index 9e27f47..4f34237 100644
--- a/ext/flowable/flowable-bpmn/src/main/resources/workflowFlowableContext.xml
+++ b/ext/flowable/flowable-bpmn/src/main/resources/workflowFlowableContext.xml
@@ -38,6 +38,8 @@ under the License.
<property name="idmEngineConfiguration" ref="syncopeIdmEngineConfiguration"/>
</bean>
+ <bean id="syncopeFormHandlerHelper" class="org.apache.syncope.core.flowable.support.SyncopeFormHandlerHelper"/>
+
<bean class="org.apache.syncope.core.flowable.support.DomainProcessEngineConfiguration" scope="prototype">
<property name="databaseSchemaUpdate" value="true"/>
@@ -52,6 +54,8 @@ under the License.
<bean class="org.apache.syncope.core.flowable.support.SyncopeEntitiesVariableType"/>
</list>
</property>
+
+ <property name="formHandlerHelper" ref="syncopeFormHandlerHelper"/>
</bean>
<bean id="bpmnProcessManager" class="org.apache.syncope.core.flowable.impl.FlowableBpmnProcessManager"/>
http://git-wip-us.apache.org/repos/asf/syncope/blob/fee1317d/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/BpmnProcessLogic.java
----------------------------------------------------------------------
diff --git a/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/BpmnProcessLogic.java b/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/BpmnProcessLogic.java
index 8d280ac..ad76605 100644
--- a/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/BpmnProcessLogic.java
+++ b/ext/flowable/logic/src/main/java/org/apache/syncope/core/logic/BpmnProcessLogic.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.logic;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.List;
-import org.apache.syncope.common.lib.to.BpmnProcessTO;
+import org.apache.syncope.common.lib.to.BpmnProcess;
import org.apache.syncope.common.lib.types.FlowableEntitlement;
import org.apache.syncope.common.lib.types.BpmnProcessFormat;
import org.springframework.beans.factory.annotation.Autowired;
@@ -31,14 +31,14 @@ import org.springframework.transaction.annotation.Transactional;
import org.apache.syncope.core.flowable.api.BpmnProcessManager;
@Component
-public class BpmnProcessLogic extends AbstractTransactionalLogic<BpmnProcessTO> {
+public class BpmnProcessLogic extends AbstractTransactionalLogic<BpmnProcess> {
@Autowired
private BpmnProcessManager bpmnProcessManager;
@PreAuthorize("hasRole('" + FlowableEntitlement.BPMN_PROCESS_LIST + "')")
@Transactional(readOnly = true)
- public List<BpmnProcessTO> list() {
+ public List<BpmnProcess> list() {
return bpmnProcessManager.getProcesses();
}
@@ -65,7 +65,7 @@ public class BpmnProcessLogic extends AbstractTransactionalLogic<BpmnProcessTO>
}
@Override
- protected BpmnProcessTO resolveReference(final Method method, final Object... args)
+ protected BpmnProcess resolveReference(final Method method, final Object... args)
throws UnresolvedReferenceException {
throw new UnresolvedReferenceException();