/** * Use this constructor in subclasses to provide a custom * {@link ExceptionHandler}. * * @param exceptionHandler an {@link ExceptionHandler} instance * @param serviceDecorators an array of ServiceLayerDecorators that change how * the RequestFactory request processor interact with the domain * objects */ public RequestFactoryServlet(ExceptionHandler exceptionHandler, ServiceLayerDecorator... serviceDecorators) { processor = new SimpleRequestProcessor(ServiceLayer.create(serviceDecorators)); processor.setExceptionHandler(exceptionHandler); }
/** * Process a payload sent by a RequestFactory client. * * @param payload the payload sent by the client * @return a payload to return to the client */ public String process(String payload) { RequestMessage req = AutoBeanCodex.decode(FACTORY, RequestMessage.class, payload).as(); AutoBean<ResponseMessage> responseBean = FACTORY.response(); try { process(req, responseBean.as()); } catch (ReportableException e) { // Create a new response envelope, since the state is unknown responseBean = FACTORY.response(); responseBean.as().setGeneralFailure(createFailureMessage(e).as()); } // Return a JSON-formatted payload return AutoBeanCodex.encode(responseBean).getPayload(); }
/** * Turn a domain value into a wire format message. */ public Splittable flatten(Object domainValue) { Splittable flatValue; if (ValueCodex.canDecode(domainValue.getClass())) { flatValue = ValueCodex.encode(domainValue); } else { flatValue = new SimpleRequestProcessor(service).createOobMessage(Collections .singletonList(domainValue)); } return flatValue; }
/** * Decode an out-of-band message. */ <T> List<T> decodeOobMessage(Class<T> domainClass, Splittable payload) { Class<?> proxyType = service.resolveClientType(domainClass, BaseProxy.class, true); RequestState state = new RequestState(service); RequestMessage message = AutoBeanCodex.decode(FACTORY, RequestMessage.class, payload).as(); processOperationMessages(state, message); List<Object> decoded = decodeInvocationArguments(state, message.getInvocations().get(0).getParameters(), new Class<?>[] {proxyType}, new Type[] {domainClass}); @SuppressWarnings("unchecked") List<T> toReturn = (List<T>) decoded; return toReturn; }
processOperationMessages(source, req); List<ViolationMessage> errorMessages = validateEntities(source); processInvocationMessages(source, req, invocationResults, invocationSuccess, returnState); toProcess.putAll(source.beans); toProcess.putAll(returnState.beans); createReturnOperations(operations, returnState, toProcess);
domainParam = ValueCodex.decode(param, split); } else { domainParam = new SimpleRequestProcessor(service).decodeOobMessage(param, split).get(0);
public void send(String payload, TransportReceiver receiver) { String result; try { if (DUMP_PAYLOAD) { System.out.println(">>> " + payload); } result = processor.process(payload); if (DUMP_PAYLOAD) { System.out.println("<<< " + result); } } catch (RuntimeException e) { e.printStackTrace(); receiver.onTransportFailure(new ServerFailure(e.getMessage())); return; } receiver.onTransportSuccess(result); } }
List<Object> args = decodeInvocationArguments(state, invocation, contextMethod); domainReturnValue = AutoBeanCodex.encode(createFailureMessage(e)); ok = false;
String previousVersion = bean.<String> getTag(Constants.VERSION_PROPERTY_B64); if (version != null && previousVersion != null && version.equals(fromBase64(previousVersion))) { continue; op.setServerId(toBase64(id.getServerId())); op.setVersion(toBase64(version.getPayload()));
/** * Get or create BaseProxy AutoBeans for a list of id-bearing messages. */ public List<AutoBean<? extends BaseProxy>> getBeansForPayload(List<? extends IdMessage> idMessages) { List<SimpleProxyId<?>> ids = new ArrayList<SimpleProxyId<?>>(idMessages.size()); for (IdMessage idMessage : idMessages) { SimpleProxyId<?> id; if (Strength.SYNTHETIC.equals(idMessage.getStrength())) { Class<? extends BaseProxy> clazz = service.resolveClass(idMessage.getTypeToken()); id = idFactory.allocateSyntheticId(clazz, idMessage.getSyntheticId()); } else { String decodedId = idMessage.getServerId() == null ? null : SimpleRequestProcessor.fromBase64(idMessage .getServerId()); id = idFactory.getId(idMessage.getTypeToken(), decodedId, idMessage.getClientId()); } ids.add(id); } return getBeansForIds(ids); }
/** * Decode the arguments to pass into the domain method. If the domain method * is not static, the instance object will be in the 0th position. */ private List<Object> decodeInvocationArguments(RequestState source, InvocationMessage invocation, Method contextMethod) { boolean isStatic = Request.class.isAssignableFrom(contextMethod.getReturnType()); int baseLength = contextMethod.getParameterTypes().length; int length = baseLength + (isStatic ? 0 : 1); int offset = isStatic ? 0 : 1; Class<?>[] contextArgs = new Class<?>[length]; Type[] genericArgs = new Type[length]; if (!isStatic) { genericArgs[0] = TypeUtils.getSingleParameterization(InstanceRequest.class, contextMethod .getGenericReturnType()); contextArgs[0] = TypeUtils.ensureBaseType(genericArgs[0]); } System.arraycopy(contextMethod.getParameterTypes(), 0, contextArgs, offset, baseLength); System.arraycopy(contextMethod.getGenericParameterTypes(), 0, genericArgs, offset, baseLength); List<Object> args = decodeInvocationArguments(source, invocation.getParameters(), contextArgs, genericArgs); return args; }
map.putAll(state.beans); List<OperationMessage> operations = new ArrayList<OperationMessage>(); createReturnOperations(operations, state, map);
processOperationMessages(source, req); List<ViolationMessage> errorMessages = validateEntities(source); processInvocationMessages(source, req, invocationResults, invocationSuccess, returnState); toProcess.putAll(source.beans); toProcess.putAll(returnState.beans); createReturnOperations(operations, returnState, toProcess);
domainParam = ValueCodex.decode(param, split); } else { domainParam = new SimpleRequestProcessor(service).decodeOobMessage(param, split).get(0);
String payload = processor.process(jsonRequestString); if (DUMP_PAYLOAD) { System.out.println("<<< " + payload);
/** * Decode an out-of-band message. */ <T> List<T> decodeOobMessage(Class<T> domainClass, Splittable payload) { Class<?> proxyType = service.resolveClientType(domainClass, BaseProxy.class, true); RequestState state = new RequestState(service); RequestMessage message = AutoBeanCodex.decode(FACTORY, RequestMessage.class, payload).as(); processOperationMessages(state, message); List<Object> decoded = decodeInvocationArguments(state, message.getInvocations().get(0).getParameters(), new Class<?>[] {proxyType}, new Type[] {domainClass}); @SuppressWarnings("unchecked") List<T> toReturn = (List<T>) decoded; return toReturn; }
List<Object> args = decodeInvocationArguments(state, invocation, contextMethod); domainReturnValue = AutoBeanCodex.encode(createFailureMessage(e)); ok = false;
String previousVersion = bean.<String> getTag(Constants.VERSION_PROPERTY_B64); if (version != null && previousVersion != null && version.equals(fromBase64(previousVersion))) { continue; op.setServerId(toBase64(id.getServerId())); op.setVersion(toBase64(version.getPayload()));
/** * Get or create BaseProxy AutoBeans for a list of id-bearing messages. */ public List<AutoBean<? extends BaseProxy>> getBeansForPayload(List<? extends IdMessage> idMessages) { List<SimpleProxyId<?>> ids = new ArrayList<SimpleProxyId<?>>(idMessages.size()); for (IdMessage idMessage : idMessages) { SimpleProxyId<?> id; if (Strength.SYNTHETIC.equals(idMessage.getStrength())) { Class<? extends BaseProxy> clazz = service.resolveClass(idMessage.getTypeToken()); id = idFactory.allocateSyntheticId(clazz, idMessage.getSyntheticId()); } else { String decodedId = idMessage.getServerId() == null ? null : SimpleRequestProcessor.fromBase64(idMessage .getServerId()); id = idFactory.getId(idMessage.getTypeToken(), decodedId, idMessage.getClientId()); } ids.add(id); } return getBeansForIds(ids); }
/** * Decode the arguments to pass into the domain method. If the domain method * is not static, the instance object will be in the 0th position. */ private List<Object> decodeInvocationArguments(RequestState source, InvocationMessage invocation, Method contextMethod) { boolean isStatic = Request.class.isAssignableFrom(contextMethod.getReturnType()); int baseLength = contextMethod.getParameterTypes().length; int length = baseLength + (isStatic ? 0 : 1); int offset = isStatic ? 0 : 1; Class<?>[] contextArgs = new Class<?>[length]; Type[] genericArgs = new Type[length]; if (!isStatic) { genericArgs[0] = TypeUtils.getSingleParameterization(InstanceRequest.class, contextMethod .getGenericReturnType()); contextArgs[0] = TypeUtils.ensureBaseType(genericArgs[0]); } System.arraycopy(contextMethod.getParameterTypes(), 0, contextArgs, offset, baseLength); System.arraycopy(contextMethod.getGenericParameterTypes(), 0, genericArgs, offset, baseLength); List<Object> args = decodeInvocationArguments(source, invocation.getParameters(), contextArgs, genericArgs); return args; }