| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package org.chromium.sdk.internal.wip; | |
| 6 | |
| 7 import java.util.LinkedHashMap; | |
| 8 import java.util.Map; | |
| 9 | |
| 10 import org.chromium.sdk.CallbackSemaphore; | |
| 11 import org.chromium.sdk.JsEvaluateContext; | |
| 12 import org.chromium.sdk.JsObject; | |
| 13 import org.chromium.sdk.JsValue; | |
| 14 import org.chromium.sdk.JsVariable; | |
| 15 import org.chromium.sdk.RelayOk; | |
| 16 import org.chromium.sdk.RemoteValueMapping; | |
| 17 import org.chromium.sdk.SyncCallback; | |
| 18 import org.chromium.sdk.internal.JsEvaluateContextBase; | |
| 19 import org.chromium.sdk.internal.wip.WipExpressionBuilder.ValueNameBuilder; | |
| 20 import org.chromium.sdk.internal.wip.WipValueBuilder.JsValueBase; | |
| 21 import org.chromium.sdk.internal.wip.WipValueBuilder.SerializableValue; | |
| 22 import org.chromium.sdk.internal.wip.protocol.input.runtime.RemoteObjectValue; | |
| 23 import org.chromium.sdk.internal.wip.protocol.output.WipParamsWithResponse; | |
| 24 import org.chromium.sdk.internal.wip.protocol.output.runtime.CallArgumentParam; | |
| 25 import org.chromium.sdk.util.GenericCallback; | |
| 26 import org.chromium.sdk.util.MethodIsBlockingException; | |
| 27 import org.chromium.sdk.wip.EvaluateToMappingExtension; | |
| 28 import org.json.simple.JSONValue; | |
| 29 | |
| 30 /** | |
| 31 * Basic implementation of the abstract {@link JsEvaluateContextBase}. Class lea
ves unimplemented | |
| 32 * parts that deal with a particular context details (callframe or global) and p
articular protocol | |
| 33 * message. | |
| 34 * @param <DATA> type of protocol message response | |
| 35 */ | |
| 36 abstract class WipEvaluateContextBase<DATA> extends JsEvaluateContextBase { | |
| 37 | |
| 38 private final WipValueLoader valueLoader; | |
| 39 | |
| 40 WipEvaluateContextBase(WipValueLoader valueLoader) { | |
| 41 this.valueLoader = valueLoader; | |
| 42 } | |
| 43 | |
| 44 @Override | |
| 45 public RelayOk evaluateAsync(final String expression, | |
| 46 Map<String, ? extends JsValue> additionalContext, EvaluateCallback callbac
k, | |
| 47 SyncCallback syncCallback) { | |
| 48 | |
| 49 WipExpressionBuilder.ValueNameBuilder valueNameBuilder = | |
| 50 WipExpressionBuilder.createRootName(expression, true); | |
| 51 | |
| 52 return evaluateAsync(expression, valueNameBuilder, additionalContext, valueL
oader, | |
| 53 callback, syncCallback); | |
| 54 } | |
| 55 | |
| 56 @Override | |
| 57 public PrimitiveValueFactory getValueFactory() { | |
| 58 return PRIMITIVE_VALUE_FACTORY; | |
| 59 } | |
| 60 | |
| 61 RelayOk evaluateAsync(String expression, ValueNameBuilder valueNameBuidler, | |
| 62 Map<String, ? extends JsValue> additionalContext, EvaluateCallback callbac
k, | |
| 63 SyncCallback syncCallback) { | |
| 64 return evaluateAsync(expression, valueNameBuidler, additionalContext, valueL
oader, | |
| 65 callback, syncCallback); | |
| 66 } | |
| 67 | |
| 68 private RelayOk evaluateAsync(String expression, final ValueNameBuilder valueN
ameBuidler, | |
| 69 Map<String, ? extends JsValue> additionalContext, WipValueLoader destinati
onValueLoaderParam, | |
| 70 final EvaluateCallback callback, SyncCallback syncCallback) { | |
| 71 Map<String, JsValueBase> internalAdditionalContext; | |
| 72 if (additionalContext == null) { | |
| 73 internalAdditionalContext = null; | |
| 74 } else { | |
| 75 internalAdditionalContext = new LinkedHashMap<String, JsValueBase>(additio
nalContext.size()); | |
| 76 for (Map.Entry<String, ? extends JsValue> en : additionalContext.entrySet(
)) { | |
| 77 JsValueBase jsValueBase = JsValueBase.cast(en.getValue()); | |
| 78 internalAdditionalContext.put(en.getKey(), jsValueBase); | |
| 79 } | |
| 80 } | |
| 81 return evaluateAsyncImpl(expression, valueNameBuidler, internalAdditionalCon
text, | |
| 82 destinationValueLoaderParam, callback, syncCallback); | |
| 83 } | |
| 84 | |
| 85 RelayOk evaluateAsyncImpl(String expression, final ValueNameBuilder valueNameB
uidler, | |
| 86 Map<String, ? extends SerializableValue> additionalContext, | |
| 87 WipValueLoader destinationValueLoaderParam, | |
| 88 final EvaluateCallback callback, SyncCallback syncCallback) { | |
| 89 if (destinationValueLoaderParam == null) { | |
| 90 destinationValueLoaderParam = valueLoader; | |
| 91 } | |
| 92 final WipValueLoader destinationValueLoader = destinationValueLoaderParam; | |
| 93 if (additionalContext != null && !additionalContext.isEmpty()) { | |
| 94 WipContextBuilder contextBuilder = valueLoader.getTabImpl().getContextBuil
der(); | |
| 95 EvaluateHack evaluateHack = contextBuilder.getEvaluateHack(); | |
| 96 return evaluateHack.evaluateAsync(expression, valueNameBuidler, additional
Context, | |
| 97 destinationValueLoader, evaluateHackHelper, callback, syncCallback); | |
| 98 } | |
| 99 | |
| 100 WipParamsWithResponse<DATA> params = createRequestParams(expression, destina
tionValueLoader); | |
| 101 | |
| 102 GenericCallback<DATA> commandCallback; | |
| 103 if (callback == null) { | |
| 104 commandCallback = null; | |
| 105 } else { | |
| 106 commandCallback = new GenericCallback<DATA>() { | |
| 107 @Override | |
| 108 public void success(DATA data) { | |
| 109 ResultOrException resultOrException = | |
| 110 processResponse(data, destinationValueLoader, valueNameBuidler); | |
| 111 callback.success(resultOrException); | |
| 112 } | |
| 113 @Override | |
| 114 public void failure(Exception exception) { | |
| 115 callback.failure(exception); | |
| 116 } | |
| 117 }; | |
| 118 } | |
| 119 WipCommandProcessor commandProcessor = valueLoader.getTabImpl().getCommandPr
ocessor(); | |
| 120 return commandProcessor.send(params, commandCallback, syncCallback); | |
| 121 } | |
| 122 | |
| 123 private ResultOrException processResponse(DATA data, WipValueLoader destinatio
nValueLoader, | |
| 124 ValueNameBuilder valueNameBuidler) { | |
| 125 RemoteObjectValue valueData = getRemoteObjectValue(data); | |
| 126 | |
| 127 WipValueBuilder valueBuilder = destinationValueLoader.getValueBuilder(); | |
| 128 | |
| 129 final JsValue value = valueBuilder.wrap(valueData, valueNameBuidler.getQuali
fiedNameBuilder()); | |
| 130 | |
| 131 if (getWasThrown(data) == Boolean.TRUE) { | |
| 132 return new ResultOrException() { | |
| 133 @Override public JsValue getResult() { | |
| 134 return null; | |
| 135 } | |
| 136 @Override public JsValue getException() { | |
| 137 return value; | |
| 138 } | |
| 139 @Override public <R> R accept(Visitor<R> visitor) { | |
| 140 return visitor.visitException(value); | |
| 141 } | |
| 142 }; | |
| 143 } else { | |
| 144 return new ResultOrException() { | |
| 145 @Override public JsValue getResult() { | |
| 146 return value; | |
| 147 } | |
| 148 @Override public JsValue getException() { | |
| 149 return null; | |
| 150 } | |
| 151 @Override public <R> R accept(Visitor<R> visitor) { | |
| 152 return visitor.visitResult(value); | |
| 153 } | |
| 154 }; | |
| 155 } | |
| 156 } | |
| 157 | |
| 158 private final EvaluateHack.EvaluateCommandHandler<DATA> evaluateHackHelper = | |
| 159 new EvaluateHack.EvaluateCommandHandler<DATA>() { | |
| 160 @Override | |
| 161 public WipParamsWithResponse<DATA> createRequest( | |
| 162 String patchedUserExpression, WipValueLoader destinationValueLoader) { | |
| 163 return createRequestParams(patchedUserExpression, destinationValueLoader); | |
| 164 } | |
| 165 | |
| 166 @Override | |
| 167 public ResultOrException processResult(DATA response, WipValueLoader destina
tionValueLoader, | |
| 168 ValueNameBuilder valueNameBuidler) { | |
| 169 return processResponse(response, destinationValueLoader, valueNameBuidler)
; | |
| 170 } | |
| 171 | |
| 172 @Override | |
| 173 public Exception processFailure(Exception cause) { | |
| 174 return cause; | |
| 175 } | |
| 176 }; | |
| 177 | |
| 178 protected abstract WipParamsWithResponse<DATA> createRequestParams(String expr
ession, | |
| 179 WipValueLoader destinationValueLoader); | |
| 180 | |
| 181 protected abstract RemoteObjectValue getRemoteObjectValue(DATA data); | |
| 182 | |
| 183 protected abstract Boolean getWasThrown(DATA data); | |
| 184 | |
| 185 static WipEvaluateContextBase<?> castArgument(JsEvaluateContext context) { | |
| 186 try { | |
| 187 return (WipEvaluateContextBase<?>) context; | |
| 188 } catch (ClassCastException e) { | |
| 189 throw new IllegalArgumentException("Incorrect evaluate context argument",
e); | |
| 190 } | |
| 191 } | |
| 192 | |
| 193 static final EvaluateToMappingExtension EVALUATE_TO_MAPPING_EXTENSION = | |
| 194 new EvaluateToMappingExtension() { | |
| 195 @Override | |
| 196 public void evaluateSync(JsEvaluateContext evaluateContext, | |
| 197 String expression, Map<String, ? extends JsValue> additionalContext, | |
| 198 RemoteValueMapping targetMapping, EvaluateCallback evaluateCallback) | |
| 199 throws MethodIsBlockingException { | |
| 200 CallbackSemaphore callbackSemaphore = new CallbackSemaphore(); | |
| 201 RelayOk relayOk = evaluateAsync(evaluateContext, expression, additionalCon
text, | |
| 202 targetMapping, evaluateCallback, callbackSemaphore); | |
| 203 callbackSemaphore.acquireDefault(relayOk); | |
| 204 } | |
| 205 | |
| 206 @Override | |
| 207 public RelayOk evaluateAsync(JsEvaluateContext evaluateContext, | |
| 208 String expression, Map<String, ? extends JsValue> additionalContext, | |
| 209 RemoteValueMapping targetMapping, EvaluateCallback evaluateCallback, | |
| 210 SyncCallback syncCallback) { | |
| 211 WipEvaluateContextBase<?> contextImpl = | |
| 212 WipEvaluateContextBase.castArgument(evaluateContext); | |
| 213 return contextImpl.evaluateAsync(expression, additionalContext, | |
| 214 evaluateCallback, syncCallback); | |
| 215 } | |
| 216 }; | |
| 217 | |
| 218 private static final PrimitiveValueFactory PRIMITIVE_VALUE_FACTORY = | |
| 219 new PrimitiveValueFactory() { | |
| 220 @Override | |
| 221 public JsValueBase getUndefined() { | |
| 222 return new JsValueBaseImpl(JsValue.Type.TYPE_UNDEFINED) { | |
| 223 @Override public String getValueString() { | |
| 224 return "undefined"; | |
| 225 } | |
| 226 @Override public CallArgumentParam createCallArgumentParam() { | |
| 227 return new CallArgumentParam(false, null, null); | |
| 228 } | |
| 229 }; | |
| 230 } | |
| 231 | |
| 232 @Override | |
| 233 public JsValueBase getNull() { | |
| 234 return new JsValueBaseImpl(JsValue.Type.TYPE_NULL) { | |
| 235 @Override public String getValueString() { | |
| 236 return "null"; | |
| 237 } | |
| 238 @Override public CallArgumentParam createCallArgumentParam() { | |
| 239 return new CallArgumentParam(true, null, null); | |
| 240 } | |
| 241 }; | |
| 242 } | |
| 243 | |
| 244 @Override | |
| 245 public JsValueBase createString(String value) { | |
| 246 return new SimpleValue(JsValue.Type.TYPE_STRING, value); | |
| 247 } | |
| 248 | |
| 249 @Override | |
| 250 public JsValueBase createNumber(double value) { | |
| 251 return new SimpleValue(JsValue.Type.TYPE_NUMBER, value); | |
| 252 } | |
| 253 | |
| 254 @Override | |
| 255 public JsValueBase createNumber(long value) { | |
| 256 return new SimpleValue(JsValue.Type.TYPE_NUMBER, value); | |
| 257 } | |
| 258 | |
| 259 @Override | |
| 260 public JsValueBase createNumber(final String stringRepresentation) { | |
| 261 return new JsValueBaseImpl(JsValue.Type.TYPE_STRING) { | |
| 262 @Override public String getValueString() { | |
| 263 return stringRepresentation; | |
| 264 } | |
| 265 @Override public CallArgumentParam createCallArgumentParam() { | |
| 266 return new CallArgumentParam(true, JSONValue.parse(stringRepresentatio
n), null); | |
| 267 } | |
| 268 }; | |
| 269 } | |
| 270 | |
| 271 @Override | |
| 272 public JsValueBase createBoolean(boolean value) { | |
| 273 return new SimpleValue(JsValue.Type.TYPE_BOOLEAN, value); | |
| 274 } | |
| 275 | |
| 276 abstract class JsValueBaseImpl extends JsValueBase { | |
| 277 private final Type type; | |
| 278 JsValueBaseImpl(Type type) { | |
| 279 this.type = type; | |
| 280 } | |
| 281 @Override public Type getType() { | |
| 282 return type; | |
| 283 } | |
| 284 @Override public JsObject asObject() { | |
| 285 return null; | |
| 286 } | |
| 287 @Override public boolean isTruncated() { | |
| 288 return false; | |
| 289 } | |
| 290 @Override public RelayOk reloadHeavyValue(ReloadBiggerCallback callback, | |
| 291 SyncCallback syncCallback) { | |
| 292 throw new UnsupportedOperationException(); | |
| 293 } | |
| 294 @Override public String getRefId() { | |
| 295 return null; | |
| 296 } | |
| 297 } | |
| 298 | |
| 299 class SimpleValue extends JsValueBaseImpl { | |
| 300 private final Object value; | |
| 301 SimpleValue(Type type, Object value) { | |
| 302 super(type); | |
| 303 this.value = value; | |
| 304 } | |
| 305 @Override public String getValueString() { | |
| 306 return value.toString(); | |
| 307 } | |
| 308 @Override public CallArgumentParam createCallArgumentParam() { | |
| 309 return new CallArgumentParam(true, value, null); | |
| 310 } | |
| 311 } | |
| 312 }; | |
| 313 } | |
| OLD | NEW |