/** * Implements evaluate with additional context and destination group id operation. The * implementation modifies a global object. * * @param destinationValueLoader value loader that corresponds to the destination group * @param evaluateCommandHandler provides a particular request type */ public RelayOk evaluateAsync( String expression, Map<String, ? extends SerializableValue> additionalContext, WipValueLoader destinationValueLoader, EvaluateCommandHandler<?> evaluateCommandHandler, final JsEvaluateContext.EvaluateCallback callback, SyncCallback syncCallback) { RelaySyncCallback relaySyncCallback = new RelaySyncCallback(syncCallback); final EvaluateSession evaluateSession = new EvaluateSession( expression, additionalContext, destinationValueLoader, evaluateCommandHandler); final RelaySyncCallback.Guard guard = relaySyncCallback.newGuard(); GenericCallback<Void> postEnsureCallback = new GenericCallback<Void>() { @Override public void success(Void value) { RelayOk relayOk = evaluateSession.run(callback, guard.getRelay()); guard.discharge(relayOk); } @Override public void failure(Exception exception) { if (callback != null) { callback.failure(exception); } } }; return ensureObjectInjected(postEnsureCallback, guard.asSyncCallback()); }
/** * Makes sure that we injected a helper object inside a global object. This cannot be implemented * as step in {@link WipRelayRunner}, because the method is synchronized and cannot undergo * required control inversion. */ private synchronized RelayOk ensureObjectInjected( GenericCallback<Void> callback, SyncCallback syncCallback) { if (objectInjected) { callback.success(null); return RelaySyncCallback.finish(syncCallback); } else { objectInjected = true; return injectObject(callback, syncCallback); } }