001/* 002 * (C) Copyright 2013 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * dmetzler 018 */ 019package org.nuxeo.ecm.restapi.server.jaxrs.adapters; 020 021import javax.servlet.http.HttpServletRequest; 022import javax.ws.rs.POST; 023import javax.ws.rs.Path; 024import javax.ws.rs.PathParam; 025import javax.ws.rs.Produces; 026import javax.ws.rs.core.Context; 027import javax.ws.rs.core.MediaType; 028import javax.ws.rs.core.Response; 029 030import org.nuxeo.ecm.automation.AutomationService; 031import org.nuxeo.ecm.automation.OperationChain; 032import org.nuxeo.ecm.automation.OperationContext; 033import org.nuxeo.ecm.automation.OperationException; 034import org.nuxeo.ecm.automation.OperationType; 035import org.nuxeo.ecm.automation.core.impl.ChainTypeImpl; 036import org.nuxeo.ecm.automation.core.impl.InvokableMethod; 037import org.nuxeo.ecm.automation.jaxrs.io.operations.ExecutionRequest; 038import org.nuxeo.ecm.automation.server.AutomationServer; 039import org.nuxeo.ecm.automation.server.jaxrs.ResponseHelper; 040import org.nuxeo.ecm.automation.server.jaxrs.RestOperationException; 041import org.nuxeo.ecm.platform.web.common.exceptionhandling.ExceptionHelper; 042import org.nuxeo.ecm.webengine.WebException; 043import org.nuxeo.ecm.webengine.model.WebAdapter; 044import org.nuxeo.ecm.webengine.model.impl.DefaultAdapter; 045import org.nuxeo.runtime.api.Framework; 046 047/** 048 * @since 5.7.2 - Web adapter that expose how to run an operation on a document 049 */ 050@WebAdapter(name = OperationAdapter.NAME, type = "OperationService") 051@Produces({ "application/json+nxentity", "application/json+esentity", MediaType.APPLICATION_JSON }) 052public class OperationAdapter extends DefaultAdapter { 053 054 public static final String NAME = "op"; 055 056 @POST 057 @Path("{operationName}") 058 public Response doPost(@PathParam("operationName") String oid, @Context HttpServletRequest request, 059 ExecutionRequest xreq) { 060 try { 061 AutomationServer srv = Framework.getLocalService(AutomationServer.class); 062 if (!srv.accept(oid, false, request)) { 063 return ResponseHelper.notFound(); 064 } 065 066 AutomationService service = Framework.getLocalService(AutomationService.class); 067 068 OperationType operationType = service.getOperation(oid); 069 070 // If chain, taking the first operation to do the input lookup after 071 if (operationType instanceof ChainTypeImpl) { 072 OperationChain chain = ((ChainTypeImpl) operationType).getChain(); 073 if (!chain.getOperations().isEmpty()) { 074 operationType = service.getOperation(chain.getOperations().get(0).id()); 075 } else { 076 throw new WebException("Chain '" + oid + "' doesn't contain any operation"); 077 } 078 } 079 080 for (InvokableMethod method : operationType.getMethods()) { 081 if (getTarget().getAdapter(method.getInputType()) != null) { 082 xreq.setInput(getTarget().getAdapter(method.getInputType())); 083 break; 084 } 085 } 086 087 OperationContext ctx = xreq.createContext(request, getContext().getCoreSession()); 088 Object result = service.run(ctx, oid, xreq.getParams()); 089 090 int customHttpStatus = xreq.getRestOperationContext().getHttpStatus(); 091 if (customHttpStatus >= 100) { 092 return Response.status(customHttpStatus).entity(result).build(); 093 } 094 095 return Response.ok(result).build(); 096 } catch (OperationException cause) { 097 if (ExceptionHelper.unwrapException(cause) instanceof RestOperationException) { 098 int customHttpStatus = ((RestOperationException) ExceptionHelper.unwrapException(cause)).getStatus(); 099 throw WebException.newException("Failed to invoke operation: " + oid, cause, customHttpStatus); 100 } 101 throw WebException.newException("Failed to invoke operation: " + oid, cause); 102 } 103 104 } 105 106}