001package co.codewizards.cloudstore.ls.rest.server.service; 002 003import static co.codewizards.cloudstore.core.util.Util.*; 004import static java.util.Objects.*; 005 006import javax.ws.rs.Consumes; 007import javax.ws.rs.GET; 008import javax.ws.rs.POST; 009import javax.ws.rs.Path; 010import javax.ws.rs.PathParam; 011import javax.ws.rs.Produces; 012 013import co.codewizards.cloudstore.core.Uid; 014import co.codewizards.cloudstore.ls.core.invoke.ClassManager; 015import co.codewizards.cloudstore.ls.core.invoke.InvokeMethodExecutor; 016import co.codewizards.cloudstore.ls.core.invoke.MethodInvocationRequest; 017import co.codewizards.cloudstore.ls.core.invoke.MethodInvocationResponse; 018import co.codewizards.cloudstore.ls.core.invoke.ObjectManager; 019import co.codewizards.cloudstore.ls.core.invoke.ObjectRef; 020import co.codewizards.cloudstore.ls.core.invoke.ObjectRefWithRefId; 021import co.codewizards.cloudstore.ls.core.invoke.filter.ExtMethodInvocationRequest; 022import co.codewizards.cloudstore.ls.core.provider.MediaTypeConst; 023import co.codewizards.cloudstore.ls.rest.server.InverseInvoker; 024 025@Path("InvokeMethod") 026@Consumes(MediaTypeConst.APPLICATION_JAVA_NATIVE_WITH_OBJECT_REF) 027@Produces(MediaTypeConst.APPLICATION_JAVA_NATIVE_WITH_OBJECT_REF) 028public class InvokeMethodService extends AbstractService { 029 030 private static final InvokeMethodExecutor invokeMethodExecutor = new InvokeMethodExecutor(); 031 032 @POST 033 public MethodInvocationResponse performMethodInvocation(final MethodInvocationRequest methodInvocationRequest) throws Throwable { 034 requireNonNull(methodInvocationRequest, "methodInvocationRequest"); 035 036 // *always* acquiring to make sure the lastUseDate is updated - and to make things easy: we have what we need. 037 final InverseInvoker inverseInvoker = getInverseInvoker(); 038 final ObjectManager objectManager = inverseInvoker.getObjectManager(); 039 final ClassManager classManager = objectManager.getClassManager(); 040 041 final String className = methodInvocationRequest.getClassName(); 042 final Class<?> clazz = className == null ? null : classManager.getClassOrFail(className); 043 044 final String methodName = methodInvocationRequest.getMethodName(); 045 046 if (ObjectRef.VIRTUAL_METHOD_NAME_INC_REF_COUNT.equals(methodName)) { 047 final ObjectRefWithRefId[] objectRefWithRefIds = cast(methodInvocationRequest.getArguments()[0]); 048 for (final ObjectRefWithRefId objectRefWithRefId : objectRefWithRefIds) 049 objectManager.incRefCount(objectRefWithRefId.object, objectRefWithRefId.refId); 050 051 return MethodInvocationResponse.forInvocation(null, null); 052 } 053 else if (ObjectRef.VIRTUAL_METHOD_NAME_DEC_REF_COUNT.equals(methodName)) { 054 final ObjectRefWithRefId[] objectRefWithRefIds = cast(methodInvocationRequest.getArguments()[0]); 055 for (final ObjectRefWithRefId objectRefWithRefId : objectRefWithRefIds) 056 objectManager.decRefCount(objectRefWithRefId.object, objectRefWithRefId.refId); 057 058 return MethodInvocationResponse.forInvocation(null, null); 059 } 060 else if (ObjectRef.VIRTUAL_METHOD_CLOSE_OBJECT_MANAGER.equals(methodName)) { 061 objectManager.close(); 062 return MethodInvocationResponse.forInvocation(null, null); 063 } 064 065 final ExtMethodInvocationRequest extMethodInvocationRequest = new ExtMethodInvocationRequest(objectManager, methodInvocationRequest, clazz); 066 return invokeMethodExecutor.execute(extMethodInvocationRequest); 067 } 068 069 @GET 070 @Path("{delayedResponseId}") 071 public MethodInvocationResponse getDelayedMethodInvocationResponse(@PathParam("delayedResponseId") final Uid delayedResponseId) throws Throwable { 072 requireNonNull(delayedResponseId, "delayedResponseId"); 073 // *always* acquiring to make sure the lastUseDate is updated - and to make things easy: we have what we need. 074 getInverseInvoker().getObjectManager(); 075 076 return invokeMethodExecutor.getDelayedResponse(delayedResponseId); 077 } 078}