| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.sdk.internal.v8native; | 5 package org.chromium.sdk.internal.v8native; |
| 6 | 6 |
| 7 import java.util.ArrayList; | 7 import java.util.ArrayList; |
| 8 import java.util.List; | 8 import java.util.List; |
| 9 import java.util.Map; | 9 import java.util.Map; |
| 10 | 10 |
| 11 import org.chromium.sdk.JsEvaluateContext; | 11 import org.chromium.sdk.JsEvaluateContext; |
| 12 import org.chromium.sdk.JsValue; | 12 import org.chromium.sdk.JsValue; |
| 13 import org.chromium.sdk.JsVariable; | |
| 14 import org.chromium.sdk.RelayOk; | 13 import org.chromium.sdk.RelayOk; |
| 15 import org.chromium.sdk.SyncCallback; | 14 import org.chromium.sdk.SyncCallback; |
| 16 import org.chromium.sdk.internal.JsEvaluateContextBase; | 15 import org.chromium.sdk.internal.JsEvaluateContextBase; |
| 17 import org.chromium.sdk.internal.protocolparser.JsonProtocolParseException; | 16 import org.chromium.sdk.internal.protocolparser.JsonProtocolParseException; |
| 18 import org.chromium.sdk.internal.v8native.InternalContext.ContextDismissedChecke
dException; | 17 import org.chromium.sdk.internal.v8native.InternalContext.ContextDismissedChecke
dException; |
| 19 import org.chromium.sdk.internal.v8native.protocol.input.FailedCommandResponse.E
rrorDetails; | 18 import org.chromium.sdk.internal.v8native.protocol.input.FailedCommandResponse.E
rrorDetails; |
| 20 import org.chromium.sdk.internal.v8native.protocol.input.SuccessCommandResponse; | 19 import org.chromium.sdk.internal.v8native.protocol.input.SuccessCommandResponse; |
| 21 import org.chromium.sdk.internal.v8native.protocol.input.data.ValueHandle; | 20 import org.chromium.sdk.internal.v8native.protocol.input.data.ValueHandle; |
| 22 import org.chromium.sdk.internal.v8native.protocol.output.DebuggerMessage; | 21 import org.chromium.sdk.internal.v8native.protocol.output.DebuggerMessage; |
| 23 import org.chromium.sdk.internal.v8native.protocol.output.DebuggerMessageFactory
; | 22 import org.chromium.sdk.internal.v8native.protocol.output.DebuggerMessageFactory
; |
| 24 import org.chromium.sdk.internal.v8native.protocol.output.EvaluateMessage; | 23 import org.chromium.sdk.internal.v8native.protocol.output.EvaluateMessage; |
| 25 import org.chromium.sdk.internal.v8native.value.JsValueBase; | 24 import org.chromium.sdk.internal.v8native.value.JsValueBase; |
| 26 import org.chromium.sdk.internal.v8native.value.JsVariableBase; | 25 import org.chromium.sdk.internal.v8native.value.JsVariableBase; |
| 27 import org.chromium.sdk.internal.v8native.value.ValueMirror; | 26 import org.chromium.sdk.internal.v8native.value.ValueMirror; |
| 28 import org.chromium.sdk.util.RelaySyncCallback; | |
| 29 import org.json.simple.JSONValue; | 27 import org.json.simple.JSONValue; |
| 30 | 28 |
| 31 /** | 29 /** |
| 32 * Generic implementation of {@link JsEvaluateContext}. The abstract class leave
s unspecified | 30 * Generic implementation of {@link JsEvaluateContext}. The abstract class leave
s unspecified |
| 33 * stack frame identifier (possibly null) and reference to {@link InternalContex
t}. | 31 * stack frame identifier (possibly null) and reference to {@link InternalContex
t}. |
| 34 */ | 32 */ |
| 35 abstract class JsEvaluateContextImpl extends JsEvaluateContextBase { | 33 public abstract class JsEvaluateContextImpl extends JsEvaluateContextBase { |
| 36 public RelayOk evaluateAsyncImpl(final String expression, | 34 public RelayOk evaluateAsyncImpl(final String expression, |
| 37 Map<String, ? extends JsValue> additionalContext, | 35 Map<String, ? extends JsValue> additionalContext, |
| 38 final EvaluateCallback callback, SyncCallback syncCallback) | 36 final EvaluateCallback callback, SyncCallback syncCallback) |
| 39 throws ContextDismissedCheckedException { | 37 throws ContextDismissedCheckedException { |
| 38 List<Map.Entry<String, EvaluateMessage.Value>> internalAdditionalContext = |
| 39 convertAdditionalContextList(additionalContext, getInternalContext()); |
| 40 |
| 41 CallbackInternal callbackInternal; |
| 42 if (callback == null) { |
| 43 callbackInternal = null; |
| 44 } else { |
| 45 callbackInternal = new CallbackInternal() { |
| 46 @Override |
| 47 public void success(final JsValueBase value) { |
| 48 ResultOrException result = new ResultOrException() { |
| 49 @Override public JsValue getResult() { |
| 50 return value; |
| 51 } |
| 52 @Override public JsValue getException() { |
| 53 return null; |
| 54 } |
| 55 @Override public <R> R accept(Visitor<R> visitor) { |
| 56 return visitor.visitResult(value); |
| 57 } |
| 58 }; |
| 59 callback.success(result); |
| 60 } |
| 61 |
| 62 @Override |
| 63 public void exception(final JsValueBase exception) { |
| 64 ResultOrException result = new ResultOrException() { |
| 65 @Override public JsValue getResult() { |
| 66 return null; |
| 67 } |
| 68 @Override public JsValue getException() { |
| 69 return exception; |
| 70 } |
| 71 @Override public <R> R accept(Visitor<R> visitor) { |
| 72 return visitor.visitException(exception); |
| 73 } |
| 74 }; |
| 75 callback.success(result); |
| 76 } |
| 77 |
| 78 @Override public void failure(Exception cause) { |
| 79 callback.failure(cause); |
| 80 } |
| 81 }; |
| 82 } |
| 83 |
| 84 return evaluateAsyncInternal(expression, internalAdditionalContext, |
| 85 callbackInternal, syncCallback); |
| 86 } |
| 87 |
| 88 /** |
| 89 * Internal callback for evaluate operation. It returns internal types. |
| 90 */ |
| 91 public interface CallbackInternal { |
| 92 void success(JsValueBase value); |
| 93 void exception(JsValueBase exception); |
| 94 void failure(Exception cause); |
| 95 } |
| 96 |
| 97 public RelayOk evaluateAsyncInternal(final String expression, |
| 98 List<Map.Entry<String, EvaluateMessage.Value>> internalAdditionalContext, |
| 99 final CallbackInternal callback, SyncCallback syncCallback) |
| 100 throws ContextDismissedCheckedException { |
| 40 | 101 |
| 41 Integer frameIdentifier = getFrameIdentifier(); | 102 Integer frameIdentifier = getFrameIdentifier(); |
| 42 Boolean isGlobal = frameIdentifier == null ? Boolean.TRUE : null; | 103 Boolean isGlobal = frameIdentifier == null ? Boolean.TRUE : null; |
| 43 | 104 |
| 44 List<Map.Entry<String, EvaluateMessage.Value>> internalAdditionalContext = | |
| 45 convertAdditionalContextList(additionalContext, getInternalContext()); | |
| 46 | |
| 47 DebuggerMessage message = DebuggerMessageFactory.evaluate(expression, frameI
dentifier, | 105 DebuggerMessage message = DebuggerMessageFactory.evaluate(expression, frameI
dentifier, |
| 48 isGlobal, Boolean.TRUE, internalAdditionalContext); | 106 isGlobal, Boolean.TRUE, internalAdditionalContext); |
| 49 | 107 |
| 50 V8CommandProcessor.V8HandlerCallback commandCallback = callback == null | 108 V8CommandProcessor.V8HandlerCallback commandCallback = callback == null |
| 51 ? null | 109 ? null |
| 52 : new V8CommandCallbackBase() { | 110 : new V8CommandCallbackBase() { |
| 53 @Override | 111 @Override |
| 54 public void success(SuccessCommandResponse successResponse) { | 112 public void success(SuccessCommandResponse successResponse) { |
| 55 ValueHandle body; | 113 ValueHandle body; |
| 56 try { | 114 try { |
| 57 body = successResponse.body().asEvaluateBody(); | 115 body = successResponse.body().asEvaluateBody(); |
| 58 } catch (JsonProtocolParseException e) { | 116 } catch (JsonProtocolParseException e) { |
| 59 throw new RuntimeException(e); | 117 throw new RuntimeException(e); |
| 60 } | 118 } |
| 61 InternalContext internalContext = getInternalContext(); | 119 InternalContext internalContext = getInternalContext(); |
| 62 ValueMirror mirror = internalContext.getValueLoader().addDataToMap(b
ody); | 120 ValueMirror mirror = internalContext.getValueLoader().addDataToMap(b
ody); |
| 63 final JsValue value = | 121 JsValueBase value = |
| 64 JsVariableBase.createValue(internalContext.getValueLoader(), mir
ror); | 122 JsVariableBase.createValue(internalContext.getValueLoader(), mir
ror); |
| 65 ResultOrException result = new ResultOrException() { | 123 callback.success(value); |
| 66 @Override public JsValue getResult() { | |
| 67 return value; | |
| 68 } | |
| 69 @Override public JsValue getException() { | |
| 70 return null; | |
| 71 } | |
| 72 @Override public <R> R accept(Visitor<R> visitor) { | |
| 73 return visitor.visitResult(value); | |
| 74 } | |
| 75 }; | |
| 76 callback.success(result); | |
| 77 } | 124 } |
| 78 @Override | 125 @Override |
| 79 public void failure(String message, ErrorDetails errorDetails) { | 126 public void failure(String message, ErrorDetails errorDetails) { |
| 80 // We are not fully correct here. | 127 // We are not fully correct here. |
| 81 // All that we actually receive from the other side is a string mess
age. | 128 // All that we actually receive from the other side is a string mess
age. |
| 82 // It might be message of exception or it could be diagnostic of any
other | 129 // It might be message of exception or it could be diagnostic of any
other |
| 83 // kind of error. | 130 // kind of error. |
| 84 // We incorrectly create string value out of this message and return | 131 // We incorrectly create string value out of this message and return |
| 85 // it as an exception. | 132 // it as an exception. |
| 86 // TODO: Return actual exception value when protocol supports it. | 133 // TODO: Return actual exception value when protocol supports it. |
| 87 final JsValue pseudoException = getValueFactory().createString(messa
ge); | 134 JsValueBase pseudoException = getValueFactory().createString(message
); |
| 88 ResultOrException result = new ResultOrException() { | 135 callback.exception(pseudoException); |
| 89 @Override public JsValue getResult() { | |
| 90 return null; | |
| 91 } | |
| 92 @Override public JsValue getException() { | |
| 93 return pseudoException; | |
| 94 } | |
| 95 @Override public <R> R accept(Visitor<R> visitor) { | |
| 96 return visitor.visitException(pseudoException); | |
| 97 } | |
| 98 }; | |
| 99 callback.success(result); | |
| 100 } | 136 } |
| 101 }; | 137 }; |
| 102 | 138 |
| 103 return getInternalContext().sendV8CommandAsync(message, true, commandCallbac
k, | 139 return getInternalContext().sendV8CommandAsync(message, true, commandCallbac
k, |
| 104 syncCallback); | 140 syncCallback); |
| 105 } | 141 } |
| 106 | 142 |
| 107 @Override | 143 @Override |
| 108 public RelayOk evaluateAsync(final String expression, | 144 public RelayOk evaluateAsync(final String expression, |
| 109 Map<String, ? extends JsValue> additionalContext, | 145 Map<String, ? extends JsValue> additionalContext, |
| 110 final EvaluateCallback callback, SyncCallback syncCallback) { | 146 final EvaluateCallback callback, SyncCallback syncCallback) { |
| 111 try { | 147 try { |
| 112 return evaluateAsyncImpl(expression, additionalContext, callback, syncCall
back); | 148 return evaluateAsyncImpl(expression, additionalContext, callback, syncCall
back); |
| 113 } catch (ContextDismissedCheckedException e) { | 149 } catch (ContextDismissedCheckedException e) { |
| 114 maybeRethrowContextException(e); | 150 return maybeRethrowContextException(e, syncCallback); |
| 115 // or | |
| 116 callback.failure(e); | |
| 117 return RelaySyncCallback.finish(syncCallback); | |
| 118 } | 151 } |
| 119 } | 152 } |
| 120 | 153 |
| 121 @Override public PrimitiveValueFactory getValueFactory() { | 154 @Override public PrimitiveValueFactoryImpl getValueFactory() { |
| 122 return PRIMITIVE_VALUE_FACTORY; | 155 return PrimitiveValueFactoryImpl.INSTANCE; |
| 123 } | 156 } |
| 124 | 157 |
| 125 private void maybeRethrowContextException(ContextDismissedCheckedException ex)
{ | 158 private RelayOk maybeRethrowContextException(ContextDismissedCheckedException
ex, |
| 126 getInternalContext().getDebugSession().maybeRethrowContextException(ex); | 159 SyncCallback syncCallback) { |
| 160 return getInternalContext().getDebugSession().maybeRethrowContextException(e
x, syncCallback); |
| 127 } | 161 } |
| 128 | 162 |
| 129 | 163 |
| 130 private static List<Map.Entry<String, EvaluateMessage.Value>> convertAdditiona
lContextList( | 164 private static List<Map.Entry<String, EvaluateMessage.Value>> convertAdditiona
lContextList( |
| 131 Map<String, ? extends JsValue> source, InternalContext internalContext) { | 165 Map<String, ? extends JsValue> source, InternalContext internalContext) { |
| 132 if (source == null) { | 166 if (source == null) { |
| 133 return null; | 167 return null; |
| 134 } | 168 } |
| 135 final List<Map.Entry<String, EvaluateMessage.Value>> dataList = | 169 final List<Map.Entry<String, EvaluateMessage.Value>> dataList = |
| 136 new ArrayList<Map.Entry<String,EvaluateMessage.Value>>(source.size()); | 170 new ArrayList<Map.Entry<String,EvaluateMessage.Value>>(source.size()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 154 return dataList; | 188 return dataList; |
| 155 } | 189 } |
| 156 | 190 |
| 157 /** | 191 /** |
| 158 * @return frame identifier or null if the context is not frame-related | 192 * @return frame identifier or null if the context is not frame-related |
| 159 */ | 193 */ |
| 160 protected abstract Integer getFrameIdentifier(); | 194 protected abstract Integer getFrameIdentifier(); |
| 161 | 195 |
| 162 protected abstract InternalContext getInternalContext(); | 196 protected abstract InternalContext getInternalContext(); |
| 163 | 197 |
| 164 private static final PrimitiveValueFactory PRIMITIVE_VALUE_FACTORY = | 198 public static class PrimitiveValueFactoryImpl implements PrimitiveValueFactory
{ |
| 165 new PrimitiveValueFactory() { | 199 private static final PrimitiveValueFactoryImpl INSTANCE = |
| 200 new PrimitiveValueFactoryImpl(); |
| 201 |
| 166 @Override public JsValue getUndefined() { | 202 @Override public JsValue getUndefined() { |
| 167 return new JsValueBase.Impl(JsValue.Type.TYPE_UNDEFINED, null); | 203 return new JsValueBase.Impl(JsValue.Type.TYPE_UNDEFINED, null); |
| 168 } | 204 } |
| 169 @Override public JsValue getNull() { | 205 @Override public JsValue getNull() { |
| 170 return new JsValueBase.Impl(JsValue.Type.TYPE_NULL, null); | 206 return new JsValueBase.Impl(JsValue.Type.TYPE_NULL, null); |
| 171 } | 207 } |
| 172 @Override public JsValue createString(String value) { | 208 @Override public JsValueBase createString(String value) { |
| 173 return new JsValueBase.Impl(JsValue.Type.TYPE_STRING, value); | 209 return new JsValueBase.Impl(JsValue.Type.TYPE_STRING, value); |
| 174 } | 210 } |
| 175 @Override public JsValue createNumber(double value) { | 211 @Override public JsValue createNumber(double value) { |
| 176 return new JsValueBase.Impl(JsValue.Type.TYPE_NUMBER, JSONValue.toJSONStri
ng(value)); | 212 return new JsValueBase.Impl(JsValue.Type.TYPE_NUMBER, JSONValue.toJSONStri
ng(value)); |
| 177 } | 213 } |
| 178 @Override public JsValue createNumber(long value) { | 214 @Override public JsValue createNumber(long value) { |
| 179 return new JsValueBase.Impl(JsValue.Type.TYPE_NUMBER, JSONValue.toJSONStri
ng(value)); | 215 return new JsValueBase.Impl(JsValue.Type.TYPE_NUMBER, JSONValue.toJSONStri
ng(value)); |
| 180 } | 216 } |
| 181 @Override public JsValue createNumber(String stringRepresentation) { | 217 @Override public JsValue createNumber(String stringRepresentation) { |
| 182 return new JsValueBase.Impl(JsValue.Type.TYPE_NUMBER, stringRepresentation
); | 218 return new JsValueBase.Impl(JsValue.Type.TYPE_NUMBER, stringRepresentation
); |
| 183 } | 219 } |
| 184 @Override public JsValue createBoolean(boolean value) { | 220 @Override public JsValue createBoolean(boolean value) { |
| 185 return new JsValueBase.Impl(JsValue.Type.TYPE_BOOLEAN, JSONValue.toJSONStr
ing(value)); | 221 return new JsValueBase.Impl(JsValue.Type.TYPE_BOOLEAN, JSONValue.toJSONStr
ing(value)); |
| 186 } | 222 } |
| 187 }; | 223 } |
| 188 } | 224 } |
| OLD | NEW |