// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package org.chromium.sdk.internal.wip; import java.util.List; import org.chromium.sdk.RelayOk; import org.chromium.sdk.Script; import org.chromium.sdk.SyncCallback; import org.chromium.sdk.internal.ScriptBase; import org.chromium.sdk.internal.liveeditprotocol.LiveEditProtocolParserAccess; import org.chromium.sdk.internal.liveeditprotocol.LiveEditResult; import org.chromium.sdk.internal.protocolparser.JsonProtocolParseException; import org.chromium.sdk.internal.wip.protocol.input.debugger.CallFrameValue; import org.chromium.sdk.internal.wip.protocol.input.debugger.SetScriptSourceData; import org.chromium.sdk.internal.wip.protocol.output.debugger.SetScriptSourceParams; import org.chromium.sdk.util.GenericCallback; import org.chromium.sdk.util.RelaySyncCallback; /** * Wip implementation of {@link Script}. */ class WipScriptImpl extends ScriptBase<String> { private final WipScriptManager scriptManager; WipScriptImpl(WipScriptManager scriptManager, Descriptor<String> descriptor) { super(descriptor); this.scriptManager = scriptManager; } @Override public RelayOk setSourceOnRemote(String newSource, UpdateCallback callback, SyncCallback syncCallback) { return sendLiveEditRequest(newSource, false, callback, syncCallback); } @Override public RelayOk previewSetSource(String newSource, UpdateCallback callback, SyncCallback syncCallback) { return sendLiveEditRequest(newSource, true, callback, syncCallback); } private RelayOk sendLiveEditRequest(String newSource, final boolean preview, final UpdateCallback updateCallback, final SyncCallback syncCallback) { RelaySyncCallback relay = new RelaySyncCallback(syncCallback); final RelaySyncCallback.Guard guard = relay.newGuard(); SetScriptSourceParams params = new SetScriptSourceParams(getId(), newSource, preview); GenericCallback<SetScriptSourceData> commandCallback = new GenericCallback<SetScriptSourceData>() { @Override public void success(SetScriptSourceData value) { RelayOk relayOk = possiblyUpdateCallFrames(preview, value, updateCallback, guard.getRelay()); guard.discharge(relayOk); } @Override public void failure(Exception exception) { updateCallback.failure(exception.getMessage()); } }; WipCommandProcessor commandProcessor = scriptManager.getTabImpl().getCommandProcessor(); return commandProcessor.send(params, commandCallback, guard.asSyncCallback()); } private RelayOk possiblyUpdateCallFrames(boolean preview, final SetScriptSourceData data, final UpdateCallback updateCallback, RelaySyncCallback relay) { // TODO: support 'step-in recommended'. List<CallFrameValue> callFrames = null; if (!preview) { callFrames = data.callFrames(); } if (callFrames == null) { dispatchResult(data.result(), updateCallback); return relay.finish(); } else { GenericCallback<Void> setFramesCallback = new GenericCallback<Void>() { @Override public void success(Void value) { dispatchResult(data.result(), updateCallback); } @Override public void failure(Exception exception) { throw new RuntimeException(exception); } }; WipContextBuilder contextBuilder = scriptManager.getTabImpl().getContextBuilder(); return contextBuilder.updateStackTrace(callFrames, setFramesCallback, relay.getUserSyncCallback()); } } private void dispatchResult(SetScriptSourceData.Result result, UpdateCallback updateCallback) { if (updateCallback != null) { LiveEditResult liveEditResult; try { liveEditResult = LiveEditProtocolParserAccess.get().parseLiveEditResult(result.getUnderlyingObject()); } catch (JsonProtocolParseException e) { throw new RuntimeException("Failed to parse LiveEdit response", e); } ChangeDescription wrappedChangeDescription = UpdateResultParser.wrapChangeDescription(liveEditResult); updateCallback.success(null, wrappedChangeDescription); } } }