001package co.codewizards.cloudstore.ls.client.handler; 002 003import static co.codewizards.cloudstore.core.util.Util.*; 004import static java.util.Objects.*; 005 006import co.codewizards.cloudstore.core.Uid; 007import co.codewizards.cloudstore.ls.core.invoke.ClassManager; 008import co.codewizards.cloudstore.ls.core.invoke.InverseMethodInvocationRequest; 009import co.codewizards.cloudstore.ls.core.invoke.InverseMethodInvocationResponse; 010import co.codewizards.cloudstore.ls.core.invoke.InvokeMethodExecutor; 011import co.codewizards.cloudstore.ls.core.invoke.MethodInvocationRequest; 012import co.codewizards.cloudstore.ls.core.invoke.MethodInvocationResponse; 013import co.codewizards.cloudstore.ls.core.invoke.ObjectManager; 014import co.codewizards.cloudstore.ls.core.invoke.ObjectRef; 015import co.codewizards.cloudstore.ls.core.invoke.ObjectRefWithRefId; 016import co.codewizards.cloudstore.ls.core.invoke.filter.ExtMethodInvocationRequest; 017 018public class InverseMethodInvocationRequestHandler extends AbstractInverseServiceRequestHandler<InverseMethodInvocationRequest, InverseMethodInvocationResponse> { 019 020 private static final InvokeMethodExecutor invokeMethodExecutor = new InvokeMethodExecutor(); 021 022 @Override 023 public InverseMethodInvocationResponse handle(final InverseMethodInvocationRequest request) throws Exception { 024 requireNonNull(request, "request"); 025 026 final MethodInvocationRequest methodInvocationRequest = request.getMethodInvocationRequest(); 027 if (methodInvocationRequest != null) { 028 final MethodInvocationResponse response = performMethodInvocation(methodInvocationRequest); 029 return new InverseMethodInvocationResponse(request, response); 030 } 031 032 final Uid delayedResponseId = request.getDelayedResponseId(); 033 if (delayedResponseId != null) { 034 final MethodInvocationResponse response = getDelayedMethodInvocationResponse(delayedResponseId); 035 return new InverseMethodInvocationResponse(request, response); 036 } 037 038 throw new IllegalArgumentException("request.methodInvocationRequest and request.delayedResponseId are both null!"); 039 } 040 041 private MethodInvocationResponse performMethodInvocation(final MethodInvocationRequest methodInvocationRequest) throws Exception { 042 requireNonNull(methodInvocationRequest, "methodInvocationRequest"); 043 044 final ObjectManager objectManager = getLocalServerClient().getObjectManager(); 045 final ClassManager classManager = objectManager.getClassManager(); 046 047 final String className = methodInvocationRequest.getClassName(); 048 final Class<?> clazz = className == null ? null : classManager.getClassOrFail(className); 049 050 final String methodName = methodInvocationRequest.getMethodName(); 051 052 if (ObjectRef.VIRTUAL_METHOD_NAME_INC_REF_COUNT.equals(methodName)) { 053 final ObjectRefWithRefId[] objectRefWithRefIds = cast(methodInvocationRequest.getArguments()[0]); 054 for (final ObjectRefWithRefId objectRefWithRefId : objectRefWithRefIds) 055 objectManager.incRefCount(objectRefWithRefId.object, objectRefWithRefId.refId); 056 057 return MethodInvocationResponse.forInvocation(null, null); 058 } 059 else if (ObjectRef.VIRTUAL_METHOD_NAME_DEC_REF_COUNT.equals(methodName)) { 060 final ObjectRefWithRefId[] objectRefWithRefIds = cast(methodInvocationRequest.getArguments()[0]); 061 for (final ObjectRefWithRefId objectRefWithRefId : objectRefWithRefIds) 062 objectManager.decRefCount(objectRefWithRefId.object, objectRefWithRefId.refId); 063 064 return MethodInvocationResponse.forInvocation(null, null); 065 } 066 067 final ExtMethodInvocationRequest extMethodInvocationRequest = new ExtMethodInvocationRequest(objectManager, methodInvocationRequest, clazz); 068 final MethodInvocationResponse response = invokeMethodExecutor.execute(extMethodInvocationRequest); 069 return response; 070 071// InvocationFilterRegistry.getInstance().assertCanInvoke(extMethodInvocationRequest); 072// 073// final String[] argumentTypeNames = methodInvocationRequest.getArgumentTypeNames(); 074// final Class<?>[] argumentTypes = argumentTypeNames == null ? null : classManager.getClassesOrFail(argumentTypeNames); 075// 076// final Object[] arguments = methodInvocationRequest.getArguments(); 077// 078// Object resultObject = null; 079// 080// final InvocationType invocationType = methodInvocationRequest.getInvocationType(); 081// 082// objectManager.getReferenceCleanerRegistry().preInvoke(extMethodInvocationRequest); 083// 084// Throwable error = null; 085// try { 086// switch (invocationType) { 087// case CONSTRUCTOR: 088// resultObject = invokeConstructor(clazz, arguments); 089// break; 090// case OBJECT: 091// resultObject = invoke(object, methodName, argumentTypes, arguments); 092// break; 093// case STATIC: 094// resultObject = invokeStatic(clazz, methodName, arguments); 095// break; 096// default: 097// throw new IllegalStateException("Unknown InvocationType: " + invocationType); 098// } 099// } catch (Throwable x) { 100// error = x; 101// } finally { 102// objectManager.getReferenceCleanerRegistry().postInvoke(extMethodInvocationRequest, resultObject, error); 103// } 104// 105// if (error != null) { 106// if (error instanceof RuntimeException) 107// throw (RuntimeException) error; 108// else if (error instanceof Error) 109// throw (Error) error; 110// else 111// throw new RuntimeException(error); 112// } 113// 114// return new InverseMethodInvocationResponse(request, MethodInvocationResponse.forInvocation(resultObject)); 115 } 116 117 private MethodInvocationResponse getDelayedMethodInvocationResponse(final Uid delayedResponseId) throws Exception { 118 requireNonNull(delayedResponseId, "delayedResponseId"); 119 return invokeMethodExecutor.getDelayedResponse(delayedResponseId); 120 } 121}