001/*
002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     <a href="mailto:grenard@nuxeo.com">Guillaume Renard</a>
016 *
017 */
018
019package org.nuxeo.ecm.restapi.server.jaxrs.routing;
020
021import java.util.List;
022
023import javax.ws.rs.Consumes;
024import javax.ws.rs.DELETE;
025import javax.ws.rs.GET;
026import javax.ws.rs.POST;
027import javax.ws.rs.Path;
028import javax.ws.rs.PathParam;
029import javax.ws.rs.Produces;
030import javax.ws.rs.QueryParam;
031import javax.ws.rs.core.MediaType;
032import javax.ws.rs.core.Response;
033import javax.ws.rs.core.Response.Status;
034
035import org.apache.commons.logging.Log;
036import org.apache.commons.logging.LogFactory;
037import org.nuxeo.ecm.core.api.DocumentModel;
038import org.nuxeo.ecm.core.api.IdRef;
039import org.nuxeo.ecm.core.api.NuxeoException;
040import org.nuxeo.ecm.core.api.NuxeoPrincipal;
041import org.nuxeo.ecm.platform.routing.api.DocumentRoute;
042import org.nuxeo.ecm.platform.routing.api.DocumentRoutingService;
043import org.nuxeo.ecm.platform.routing.core.api.DocumentRoutingEngineService;
044import org.nuxeo.ecm.platform.routing.core.impl.jsongraph.JsonGraphRoute;
045import org.nuxeo.ecm.restapi.server.jaxrs.routing.model.WorkflowRequest;
046import org.nuxeo.ecm.webengine.WebException;
047import org.nuxeo.ecm.webengine.model.WebObject;
048import org.nuxeo.ecm.webengine.model.exceptions.WebSecurityException;
049import org.nuxeo.ecm.webengine.model.impl.DefaultObject;
050import org.nuxeo.runtime.api.Framework;
051
052/**
053 * @since 7.2
054 */
055@WebObject(type = "workflow")
056@Produces(MediaType.APPLICATION_JSON)
057public class WorkflowObject extends DefaultObject {
058
059    private static Log log = LogFactory.getLog(WorkflowObject.class);
060
061    private DocumentRoutingService documentRoutingService;
062
063    @Override
064    protected void initialize(Object... args) {
065        documentRoutingService = Framework.getService(DocumentRoutingService.class);
066    }
067
068    @POST
069    @Consumes({ MediaType.APPLICATION_JSON, "application/json+nxentity" })
070    @Produces(MediaType.APPLICATION_JSON)
071    public Response createWorkflowInstance(WorkflowRequest workflowRequest) {
072        final String workflowInstanceId = documentRoutingService.createNewInstance(
073                workflowRequest.getWorkflowModelName(), workflowRequest.getAttachedDocumentIds(), ctx.getCoreSession(),
074                true);
075        DocumentModel workflowInstance = getContext().getCoreSession().getDocument(new IdRef(workflowInstanceId));
076        DocumentRoute route = workflowInstance.getAdapter(DocumentRoute.class);
077        return Response.ok(route).status(Status.CREATED).build();
078    }
079
080    @GET
081    @Path("{workflowInstanceId}")
082    public DocumentRoute getWorkflowInstance(@PathParam("workflowInstanceId") String workflowInstanceId) {
083        DocumentModel workflowInstance;
084        try {
085            workflowInstance = getContext().getCoreSession().getDocument(new IdRef(workflowInstanceId));
086            return workflowInstance.getAdapter(DocumentRoute.class);
087        } catch (NuxeoException e) {
088            e.addInfo("Can not get workflow instance with id: " + workflowInstanceId);
089            throw e;
090        }
091    }
092
093    @GET
094    @Path("{workflowInstanceId}/graph")
095    public JsonGraphRoute getWorkflowGraph(@PathParam("workflowInstanceId") String workflowInstanceId) {
096        try {
097            return new JsonGraphRoute(getContext().getCoreSession(), workflowInstanceId, getContext().getLocale());
098        } catch (NuxeoException e) {
099            e.addInfo("Can not get workflow instance graph with id: " + workflowInstanceId);
100            throw e;
101        }
102    }
103
104    @DELETE
105    @Path("{workflowInstanceId}")
106    public Response cancelWorkflowInstance(@PathParam("workflowInstanceId") String workflowInstanceId) {
107        DocumentModel workflowInstance;
108        DocumentRoute route;
109        try {
110            workflowInstance = getContext().getCoreSession().getDocument(new IdRef(workflowInstanceId));
111            route = workflowInstance.getAdapter(DocumentRoute.class);
112            checkCancelGuards(route);
113        } catch (NuxeoException e) {
114            e.addInfo("Can not get workflow instance with id: " + workflowInstanceId);
115            throw e;
116        }
117        Framework.getService(DocumentRoutingEngineService.class).cancel(route, getContext().getCoreSession());
118        return Response.ok().status(Status.NO_CONTENT).build();
119    }
120
121    protected void checkCancelGuards(DocumentRoute route) {
122        NuxeoPrincipal currentUser = (NuxeoPrincipal) getContext().getCoreSession().getPrincipal();
123        if (currentUser.isAdministrator() || currentUser.isMemberOf("powerusers")) {
124            return;
125        }
126        try {
127            if (currentUser.getName().equals(route.getInitiator())) {
128                return;
129            }
130            throw new WebSecurityException("You don't have the permission to cancel this workflow");
131        } catch (NuxeoException e) {
132            throw WebException.wrap(e);
133        }
134    }
135
136    @GET
137    public List<DocumentRoute> getRunningWorkflowInstancesLaunchedByCurrentUser(
138            @QueryParam("workflowModelName") String worflowModelName) {
139        return documentRoutingService.getRunningWorkflowInstancesLaunchedByCurrentUser(getContext().getCoreSession(),
140                worflowModelName);
141    }
142
143}