001/* 002 * (C) Copyright 2013 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 * dmetzler 016 */ 017package org.nuxeo.ecm.restapi.server.jaxrs.adapters; 018 019import javax.servlet.http.HttpServletRequest; 020import javax.ws.rs.POST; 021import javax.ws.rs.Path; 022import javax.ws.rs.PathParam; 023import javax.ws.rs.Produces; 024import javax.ws.rs.core.Context; 025import javax.ws.rs.core.MediaType; 026import javax.ws.rs.core.Response; 027 028import org.nuxeo.ecm.automation.AutomationService; 029import org.nuxeo.ecm.automation.OperationChain; 030import org.nuxeo.ecm.automation.OperationContext; 031import org.nuxeo.ecm.automation.OperationException; 032import org.nuxeo.ecm.automation.OperationType; 033import org.nuxeo.ecm.automation.core.impl.ChainTypeImpl; 034import org.nuxeo.ecm.automation.core.impl.InvokableMethod; 035import org.nuxeo.ecm.automation.jaxrs.io.operations.ExecutionRequest; 036import org.nuxeo.ecm.automation.server.AutomationServer; 037import org.nuxeo.ecm.automation.server.jaxrs.ResponseHelper; 038import org.nuxeo.ecm.automation.server.jaxrs.RestOperationException; 039import org.nuxeo.ecm.platform.web.common.exceptionhandling.ExceptionHelper; 040import org.nuxeo.ecm.webengine.WebException; 041import org.nuxeo.ecm.webengine.model.WebAdapter; 042import org.nuxeo.ecm.webengine.model.impl.DefaultAdapter; 043import org.nuxeo.runtime.api.Framework; 044 045/** 046 * @since 5.7.2 - Web adapter that expose how to run an operation on a document 047 */ 048@WebAdapter(name = OperationAdapter.NAME, type = "OperationService") 049@Produces({ "application/json+nxentity", "application/json+esentity", MediaType.APPLICATION_JSON }) 050public class OperationAdapter extends DefaultAdapter { 051 052 public static final String NAME = "op"; 053 054 @POST 055 @Path("{operationName}") 056 public Response doPost(@PathParam("operationName") String oid, @Context HttpServletRequest request, 057 ExecutionRequest xreq) { 058 try { 059 AutomationServer srv = Framework.getLocalService(AutomationServer.class); 060 if (!srv.accept(oid, false, request)) { 061 return ResponseHelper.notFound(); 062 } 063 064 AutomationService service = Framework.getLocalService(AutomationService.class); 065 066 OperationType operationType = service.getOperation(oid); 067 068 // If chain, taking the first operation to do the input lookup after 069 if (operationType instanceof ChainTypeImpl) { 070 OperationChain chain = ((ChainTypeImpl) operationType).getChain(); 071 if (!chain.getOperations().isEmpty()) { 072 operationType = service.getOperation(chain.getOperations().get(0).id()); 073 } else { 074 throw new WebException("Chain '" + oid + "' doesn't contain any operation"); 075 } 076 } 077 078 for (InvokableMethod method : operationType.getMethods()) { 079 if (getTarget().getAdapter(method.getInputType()) != null) { 080 xreq.setInput(getTarget().getAdapter(method.getInputType())); 081 break; 082 } 083 } 084 085 OperationContext ctx = xreq.createContext(request, getContext().getCoreSession()); 086 Object result = service.run(ctx, oid, xreq.getParams()); 087 088 int customHttpStatus = xreq.getRestOperationContext().getHttpStatus(); 089 if (customHttpStatus >= 100) { 090 return Response.status(customHttpStatus).entity(result).build(); 091 } 092 093 return Response.ok(result).build(); 094 } catch (OperationException cause) { 095 if (ExceptionHelper.unwrapException(cause) instanceof RestOperationException) { 096 int customHttpStatus = ((RestOperationException) ExceptionHelper.unwrapException(cause)).getStatus(); 097 throw WebException.newException("Failed to invoke operation: " + oid, cause, customHttpStatus); 098 } 099 throw WebException.newException("Failed to invoke operation: " + oid, cause); 100 } 101 102 } 103 104}