mirror of
https://github.com/sismics/docs.git
synced 2024-11-22 14:07:55 +01:00
#159: start a route on a document
This commit is contained in:
parent
e035007070
commit
5e713f0c2a
@ -0,0 +1,39 @@
|
|||||||
|
package com.sismics.docs.core.dao.jpa;
|
||||||
|
|
||||||
|
import com.sismics.docs.core.constant.AuditLogType;
|
||||||
|
import com.sismics.docs.core.model.jpa.Route;
|
||||||
|
import com.sismics.docs.core.util.AuditLogUtil;
|
||||||
|
import com.sismics.util.context.ThreadLocalContext;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route DAO.
|
||||||
|
*
|
||||||
|
* @author bgamard
|
||||||
|
*/
|
||||||
|
public class RouteDao {
|
||||||
|
/**
|
||||||
|
* Creates a new route.
|
||||||
|
*
|
||||||
|
* @param route Route
|
||||||
|
* @param userId User ID
|
||||||
|
* @return New ID
|
||||||
|
*/
|
||||||
|
public String create(Route route, String userId) {
|
||||||
|
// Create the UUID
|
||||||
|
route.setId(UUID.randomUUID().toString());
|
||||||
|
|
||||||
|
// Create the route
|
||||||
|
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||||
|
route.setCreateDate(new Date());
|
||||||
|
em.persist(route);
|
||||||
|
|
||||||
|
// Create audit log
|
||||||
|
AuditLogUtil.create(route, AuditLogType.CREATE, userId);
|
||||||
|
|
||||||
|
return route.getId();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.sismics.docs.core.dao.jpa;
|
||||||
|
|
||||||
|
import com.sismics.docs.core.model.jpa.RouteStep;
|
||||||
|
import com.sismics.util.context.ThreadLocalContext;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route step DAO.
|
||||||
|
*
|
||||||
|
* @author bgamard
|
||||||
|
*/
|
||||||
|
public class RouteStepDao {
|
||||||
|
/**
|
||||||
|
* Creates a new route step.
|
||||||
|
*
|
||||||
|
* @param routeStep Route step
|
||||||
|
* @return New ID
|
||||||
|
*/
|
||||||
|
public String create(RouteStep routeStep) {
|
||||||
|
// Create the UUID
|
||||||
|
routeStep.setId(UUID.randomUUID().toString());
|
||||||
|
|
||||||
|
// Create the route step
|
||||||
|
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||||
|
routeStep.setCreateDate(new Date());
|
||||||
|
em.persist(routeStep);
|
||||||
|
|
||||||
|
return routeStep.getId();
|
||||||
|
}
|
||||||
|
}
|
@ -15,7 +15,7 @@ import java.util.Date;
|
|||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "T_ROUTE")
|
@Table(name = "T_ROUTE")
|
||||||
public class Route {
|
public class Route implements Loggable {
|
||||||
/**
|
/**
|
||||||
* Route ID.
|
* Route ID.
|
||||||
*/
|
*/
|
||||||
@ -29,6 +29,12 @@ public class Route {
|
|||||||
@Column(name = "RTE_IDDOCUMENT_C", nullable = false, length = 36)
|
@Column(name = "RTE_IDDOCUMENT_C", nullable = false, length = 36)
|
||||||
private String documentId;
|
private String documentId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name.
|
||||||
|
*/
|
||||||
|
@Column(name = "RTE_NAME_C", nullable = false, length = 50)
|
||||||
|
private String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creation date.
|
* Creation date.
|
||||||
*/
|
*/
|
||||||
@ -41,10 +47,61 @@ public class Route {
|
|||||||
@Column(name = "RTE_DELETEDATE_D")
|
@Column(name = "RTE_DELETEDATE_D")
|
||||||
private Date deleteDate;
|
private Date deleteDate;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Route setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDocumentId() {
|
||||||
|
return documentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Route setDocumentId(String documentId) {
|
||||||
|
this.documentId = documentId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Route setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreateDate() {
|
||||||
|
return createDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Route setCreateDate(Date createDate) {
|
||||||
|
this.createDate = createDate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDeleteDate() {
|
||||||
|
return deleteDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Route setDeleteDate(Date deleteDate) {
|
||||||
|
this.deleteDate = deleteDate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toMessage() {
|
||||||
|
return documentId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return MoreObjects.toStringHelper(this)
|
return MoreObjects.toStringHelper(this)
|
||||||
.add("id", id)
|
.add("id", id)
|
||||||
|
.add("name", name)
|
||||||
.add("documentId", documentId)
|
.add("documentId", documentId)
|
||||||
.add("createDate", createDate)
|
.add("createDate", createDate)
|
||||||
.toString();
|
.toString();
|
||||||
|
@ -84,6 +84,105 @@ public class RouteStep {
|
|||||||
@Column(name = "RTP_DELETEDATE_D")
|
@Column(name = "RTP_DELETEDATE_D")
|
||||||
private Date deleteDate;
|
private Date deleteDate;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteStep setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRouteId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteStep setRouteId(String routeId) {
|
||||||
|
this.routeId = routeId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteStep setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteStepType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteStep setType(RouteStepType type) {
|
||||||
|
this.type = type;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteStepTransition getTransition() {
|
||||||
|
return transition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteStep setTransition(RouteStepTransition transition) {
|
||||||
|
this.transition = transition;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getComment() {
|
||||||
|
return comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteStep setComment(String comment) {
|
||||||
|
this.comment = comment;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTargetId() {
|
||||||
|
return targetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteStep setTargetId(String targetId) {
|
||||||
|
this.targetId = targetId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getOrder() {
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteStep setOrder(Integer order) {
|
||||||
|
this.order = order;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreateDate() {
|
||||||
|
return createDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteStep setCreateDate(Date createDate) {
|
||||||
|
this.createDate = createDate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getEndDate() {
|
||||||
|
return endDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteStep setEndDate(Date endDate) {
|
||||||
|
this.endDate = endDate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDeleteDate() {
|
||||||
|
return deleteDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteStep setDeleteDate(Date deleteDate) {
|
||||||
|
this.deleteDate = deleteDate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return MoreObjects.toStringHelper(this)
|
return MoreObjects.toStringHelper(this)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
create table T_ROUTE_MODEL ( RTM_ID_C varchar(36) not null, RTM_NAME_C varchar(50) not null, RTM_STEPS_C varchar(5000) not null, RTM_CREATEDATE_D datetime not null, RTM_DELETEDATE_D datetime, primary key (RTM_ID_C) );
|
create table T_ROUTE_MODEL ( RTM_ID_C varchar(36) not null, RTM_NAME_C varchar(50) not null, RTM_STEPS_C varchar(5000) not null, RTM_CREATEDATE_D datetime not null, RTM_DELETEDATE_D datetime, primary key (RTM_ID_C) );
|
||||||
create cached table T_ROUTE ( RTE_ID_C varchar(36) not null, RTE_IDDOCUMENT_C varchar(36) not null, RTE_CREATEDATE_D datetime not null, RTE_DELETEDATE_D datetime, primary key (RTE_ID_C) );
|
create cached table T_ROUTE ( RTE_ID_C varchar(36) not null, RTE_IDDOCUMENT_C varchar(36) not null, RTE_NAME_C varchar(50) not null, RTE_CREATEDATE_D datetime not null, RTE_DELETEDATE_D datetime, primary key (RTE_ID_C) );
|
||||||
create cached table T_ROUTE_STEP ( RTP_ID_C varchar(36) not null, RTP_IDROUTE_C varchar(36) not null, RTP_NAME_C varchar(200) not null, RTP_TYPE_C varchar(50) not null, RTP_TRANSITION_C varchar(50), RTP_COMMENT_C varchar(500), RTP_IDTARGET_C varchar(36) not null, RTP_ORDER_N int not null, RTE_CREATEDATE_D datetime not null, RTP_ENDDATE_D datetime, RTP_DELETEDATE_D datetime, primary key (RTP_ID_C) );;
|
create cached table T_ROUTE_STEP ( RTP_ID_C varchar(36) not null, RTP_IDROUTE_C varchar(36) not null, RTP_NAME_C varchar(200) not null, RTP_TYPE_C varchar(50) not null, RTP_TRANSITION_C varchar(50), RTP_COMMENT_C varchar(500), RTP_IDTARGET_C varchar(36) not null, RTP_ORDER_N int not null, RTP_CREATEDATE_D datetime not null, RTP_ENDDATE_D datetime, RTP_DELETEDATE_D datetime, primary key (RTP_ID_C) );;
|
||||||
alter table T_ROUTE add constraint FK_RTE_IDDOCUMENT_C foreign key (RTE_IDDOCUMENT_C) references T_DOCUMENT (DOC_ID_C) on delete restrict on update restrict;
|
alter table T_ROUTE add constraint FK_RTE_IDDOCUMENT_C foreign key (RTE_IDDOCUMENT_C) references T_DOCUMENT (DOC_ID_C) on delete restrict on update restrict;
|
||||||
alter table T_ROUTE_STEP add constraint FK_RTP_IDROUTE_C foreign key (RTP_IDROUTE_C) references T_ROUTE (RTE_ID_C) on delete restrict on update restrict;
|
alter table T_ROUTE_STEP add constraint FK_RTP_IDROUTE_C foreign key (RTP_IDROUTE_C) references T_ROUTE (RTE_ID_C) on delete restrict on update restrict;
|
||||||
|
|
||||||
|
@ -201,7 +201,8 @@ public class RouteModelResource extends BaseResource {
|
|||||||
|
|
||||||
// Validate input
|
// Validate input
|
||||||
name = ValidationUtil.validateLength(name, "name", 1, 50, false);
|
name = ValidationUtil.validateLength(name, "name", 1, 50, false);
|
||||||
// TODO Validate steps data
|
steps = ValidationUtil.validateLength(steps, "steps", 1, 5000, false);
|
||||||
|
validateRouteModelSteps(steps);
|
||||||
|
|
||||||
// Get the route model
|
// Get the route model
|
||||||
RouteModelDao routeModelDao = new RouteModelDao();
|
RouteModelDao routeModelDao = new RouteModelDao();
|
||||||
|
@ -0,0 +1,118 @@
|
|||||||
|
package com.sismics.docs.rest.resource;
|
||||||
|
|
||||||
|
import com.sismics.docs.core.constant.AclTargetType;
|
||||||
|
import com.sismics.docs.core.constant.PermType;
|
||||||
|
import com.sismics.docs.core.constant.RouteStepType;
|
||||||
|
import com.sismics.docs.core.dao.jpa.*;
|
||||||
|
import com.sismics.docs.core.model.jpa.*;
|
||||||
|
import com.sismics.rest.exception.ClientException;
|
||||||
|
import com.sismics.rest.exception.ForbiddenClientException;
|
||||||
|
|
||||||
|
import javax.json.*;
|
||||||
|
import javax.ws.rs.FormParam;
|
||||||
|
import javax.ws.rs.NotFoundException;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import java.io.StringReader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route REST resources.
|
||||||
|
*
|
||||||
|
* @author bgamard
|
||||||
|
*/
|
||||||
|
@Path("/route")
|
||||||
|
public class RouteResource extends BaseResource {
|
||||||
|
/**
|
||||||
|
* Start a route on a document.
|
||||||
|
*
|
||||||
|
* @api {post} /route/start Start a route on a document
|
||||||
|
* @apiName PostRouteStart
|
||||||
|
* @apiRouteModel Route
|
||||||
|
* @apiParam {String} routeModelId Route model ID
|
||||||
|
* @apiParam {String} documentId Document ID
|
||||||
|
* @apiSuccess {String} status Status OK
|
||||||
|
* @apiError (client) InvalidRouteModel Invalid route model
|
||||||
|
* @apiError (client) ForbiddenError Access denied
|
||||||
|
* @apiError (client) NotFound Route model or document not found
|
||||||
|
* @apiPermission user
|
||||||
|
* @apiVersion 1.5.0
|
||||||
|
*
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("start")
|
||||||
|
public Response start(@FormParam("routeModelId") String routeModelId,
|
||||||
|
@FormParam("documentId") String documentId) {
|
||||||
|
if (!authenticate()) {
|
||||||
|
throw new ForbiddenClientException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the document
|
||||||
|
AclDao aclDao = new AclDao();
|
||||||
|
if (!aclDao.checkPermission(documentId, PermType.WRITE, getTargetIdList(null))) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the route model
|
||||||
|
RouteModelDao routeModelDao = new RouteModelDao();
|
||||||
|
RouteModel routeModel = routeModelDao.getActiveById(routeModelId);
|
||||||
|
if (routeModel == null) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the route
|
||||||
|
Route route = new Route()
|
||||||
|
.setDocumentId(documentId)
|
||||||
|
.setName(routeModel.getName());
|
||||||
|
RouteDao routeDao = new RouteDao();
|
||||||
|
routeDao.create(route, principal.getId());
|
||||||
|
|
||||||
|
// Create the steps
|
||||||
|
UserDao userDao = new UserDao();
|
||||||
|
GroupDao groupDao = new GroupDao();
|
||||||
|
RouteStepDao routeStepDao = new RouteStepDao();
|
||||||
|
try (JsonReader reader = Json.createReader(new StringReader(routeModel.getSteps()))) {
|
||||||
|
JsonArray stepsJson = reader.readArray();
|
||||||
|
int order = 0;
|
||||||
|
for (int i = 0; i < stepsJson.size(); i++) {
|
||||||
|
JsonObject step = stepsJson.getJsonObject(i);
|
||||||
|
JsonObject target = step.getJsonObject("target");
|
||||||
|
AclTargetType targetType = AclTargetType.valueOf(target.getString("type"));
|
||||||
|
String targetName = target.getString("name");
|
||||||
|
|
||||||
|
RouteStep routeStep = new RouteStep()
|
||||||
|
.setRouteId(route.getId())
|
||||||
|
.setName(step.getString("name"))
|
||||||
|
.setOrder(order++)
|
||||||
|
.setType(RouteStepType.valueOf(step.getString("type")));
|
||||||
|
|
||||||
|
switch (targetType) {
|
||||||
|
case USER:
|
||||||
|
User user = userDao.getActiveByUsername(targetName);
|
||||||
|
if (user != null) {
|
||||||
|
routeStep.setTargetId(user.getId());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GROUP:
|
||||||
|
Group group = groupDao.getActiveByName(targetName);
|
||||||
|
if (group != null) {
|
||||||
|
routeStep.setTargetId(group.getId());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (routeStep.getTargetId() == null) {
|
||||||
|
throw new ClientException("InvalidRouteModel", "A step has an invalid target");
|
||||||
|
}
|
||||||
|
|
||||||
|
routeStepDao.create(routeStep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always return OK
|
||||||
|
JsonObjectBuilder response = Json.createObjectBuilder()
|
||||||
|
.add("status", "ok");
|
||||||
|
return Response.ok().entity(response.build()).build();
|
||||||
|
}
|
||||||
|
}
|
@ -45,6 +45,9 @@
|
|||||||
<span ng-switch-when="RouteModel">
|
<span ng-switch-when="RouteModel">
|
||||||
<a href="#/settings/workflow/edit/{{ log.target }}">{{ log.message }}</a>
|
<a href="#/settings/workflow/edit/{{ log.target }}">{{ log.message }}</a>
|
||||||
</span>
|
</span>
|
||||||
|
<span ng-switch-when="Route">
|
||||||
|
<a ng-href="#/document/view/{{ log.message }}">{{ 'open' | translate }}</a>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
package com.sismics.docs.rest;
|
||||||
|
|
||||||
|
import com.sismics.util.filter.TokenBasedSecurityFilter;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import javax.json.JsonArray;
|
||||||
|
import javax.json.JsonObject;
|
||||||
|
import javax.ws.rs.client.Entity;
|
||||||
|
import javax.ws.rs.core.Form;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the route resource.
|
||||||
|
*
|
||||||
|
* @author bgamard
|
||||||
|
*/
|
||||||
|
public class TestRouteResource extends BaseJerseyTest {
|
||||||
|
/**
|
||||||
|
* Test the route resource.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testRouteResource() {
|
||||||
|
// Login admin
|
||||||
|
String adminToken = clientUtil.login("admin", "admin", false);
|
||||||
|
|
||||||
|
// Get all route models
|
||||||
|
JsonObject json = target().path("/routemodel")
|
||||||
|
.queryParam("sort_column", "2")
|
||||||
|
.queryParam("asc", "false")
|
||||||
|
.request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.get(JsonObject.class);
|
||||||
|
JsonArray routeModels = json.getJsonArray("routemodels");
|
||||||
|
Assert.assertEquals(1, routeModels.size());
|
||||||
|
|
||||||
|
// Create a document
|
||||||
|
long create1Date = new Date().getTime();
|
||||||
|
json = target().path("/document").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.put(Entity.form(new Form()
|
||||||
|
.param("title", "My super title document 1")
|
||||||
|
.param("description", "My super description for document 1")
|
||||||
|
.param("language", "eng")
|
||||||
|
.param("create_date", Long.toString(create1Date))), JsonObject.class);
|
||||||
|
String document1Id = json.getString("id");
|
||||||
|
|
||||||
|
// Start the default route on document1
|
||||||
|
target().path("/route/start").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.post(Entity.form(new Form()
|
||||||
|
.param("documentId", document1Id)
|
||||||
|
.param("routeModelId", routeModels.getJsonObject(0).getString("id"))), JsonObject.class);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user