Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(450)

Side by Side Diff: plugins/org.chromium.sdk.wipbackend.wk118685/src/org/chromium/sdk/internal/wip/WipBreakpointImpl.java

Issue 11829027: drop old backends (Closed) Base URL: https://chromedevtools.googlecode.com/svn/trunk
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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.ArrayList;
8 import java.util.Collection;
9 import java.util.Collections;
10 import java.util.HashSet;
11 import java.util.List;
12 import java.util.Set;
13
14 import org.chromium.sdk.Breakpoint;
15 import org.chromium.sdk.BreakpointTypeExtension;
16 import org.chromium.sdk.IgnoreCountBreakpointExtension;
17 import org.chromium.sdk.JavascriptVm.BreakpointCallback;
18 import org.chromium.sdk.RelayOk;
19 import org.chromium.sdk.SyncCallback;
20 import org.chromium.sdk.internal.ScriptRegExpBreakpointTarget;
21 import org.chromium.sdk.internal.wip.protocol.input.WipCommandResponse.Success;
22 import org.chromium.sdk.internal.wip.protocol.input.debugger.LocationValue;
23 import org.chromium.sdk.internal.wip.protocol.input.debugger.SetBreakpointByUrlD ata;
24 import org.chromium.sdk.internal.wip.protocol.input.debugger.SetBreakpointData;
25 import org.chromium.sdk.internal.wip.protocol.output.WipParamsWithResponse;
26 import org.chromium.sdk.internal.wip.protocol.output.debugger.LocationParam;
27 import org.chromium.sdk.internal.wip.protocol.output.debugger.RemoveBreakpointPa rams;
28 import org.chromium.sdk.internal.wip.protocol.output.debugger.SetBreakpointByUrl Params;
29 import org.chromium.sdk.internal.wip.protocol.output.debugger.SetBreakpointParam s;
30 import org.chromium.sdk.util.GenericCallback;
31 import org.chromium.sdk.util.RelaySyncCallback;
32
33 /**
34 * Wip-based breakpoint implementation.
35 * The implementation is based on volatile fields and expects client code to do some
36 * synchronization (serialize calls to setters, {@link #flush} and {@link #clear }).
37 */
38 public class WipBreakpointImpl implements Breakpoint {
39 private final WipBreakpointManager breakpointManager;
40
41 private final Target target;
42
43 private final int lineNumber;
44 private final int columnNumber;
45
46 private final int sdkId;
47 private volatile String protocolId = null;
48
49 private volatile String condition;
50 private volatile boolean enabled;
51 private volatile boolean isDirty;
52
53 // Access only from Dispatch thread.
54 private Set<ActualLocation> actualLocations = new HashSet<ActualLocation>(2);
55
56 public WipBreakpointImpl(WipBreakpointManager breakpointManager, int sdkId, Ta rget target,
57 int lineNumber, int columnNumber, String condition, boolean enabled) {
58 this.breakpointManager = breakpointManager;
59 this.sdkId = sdkId;
60 this.target = target;
61 this.lineNumber = lineNumber;
62 this.columnNumber = columnNumber;
63 this.condition = condition;
64 this.enabled = enabled;
65
66 this.isDirty = false;
67 }
68
69 @Override
70 public Target getTarget() {
71 return target;
72 }
73
74 @Override
75 public long getId() {
76 return sdkId;
77 }
78
79 public static final BreakpointTypeExtension TYPE_EXTENSION = new BreakpointTyp eExtension() {
80 @Override
81 public FunctionSupport getFunctionSupport() {
82 return null;
83 }
84 @Override
85 public ScriptRegExpSupport getScriptRegExpSupport() {
86 return scriptRegExpSupport;
87 }
88
89 private final ScriptRegExpSupport scriptRegExpSupport = new ScriptRegExpSupp ort() {
90 @Override
91 public Target createTarget(String regExp) {
92 return new ScriptRegExpBreakpointTarget(regExp);
93 }
94 };
95 };
96
97 @Override
98 public long getLineNumber() {
99 return lineNumber;
100 }
101
102 @Override
103 public boolean isEnabled() {
104 return enabled;
105 }
106
107 @Override
108 public void setEnabled(boolean enabled) {
109 if (enabled == this.enabled) {
110 return;
111 }
112 this.enabled = enabled;
113 isDirty = true;
114 }
115
116 @Override
117 public String getCondition() {
118 return condition;
119 }
120
121 @Override
122 public void setCondition(String condition) {
123 if (eq(this.condition, condition)) {
124 return;
125 }
126 this.condition = condition;
127 isDirty = true;
128 }
129
130 @Override
131 public IgnoreCountBreakpointExtension getIgnoreCountBreakpointExtension() {
132 return getIgnoreCountBreakpointExtensionImpl();
133 }
134
135 public static IgnoreCountBreakpointExtension getIgnoreCountBreakpointExtension Impl() {
136 // TODO(peter.rybin): implement when protocol supports.
137 return null;
138 }
139
140
141 void setRemoteData(String protocolId, Collection<ActualLocation> actualLocatio ns) {
142 this.protocolId = protocolId;
143 this.actualLocations.clear();
144 this.actualLocations.addAll(actualLocations);
145 this.breakpointManager.getDb().setIdMapping(this, protocolId);
146 }
147
148 void addResolvedLocation(LocationValue locationValue) {
149 ActualLocation location = locationFromProtocol(locationValue);
150 actualLocations.add(location);
151 }
152
153 Set<ActualLocation> getActualLocations() {
154 return actualLocations;
155 }
156
157 void clearActualLocations() {
158 actualLocations.clear();
159 }
160
161 void deleteSelfFromDb() {
162 if (protocolId != null) {
163 breakpointManager.getDb().setIdMapping(this, null);
164 }
165 breakpointManager.getDb().removeBreakpoint(this);
166 }
167
168 @Override
169 public RelayOk clear(final BreakpointCallback callback, SyncCallback syncCallb ack) {
170 // TODO: make sure this is thread-safe.
171 if (protocolId == null) {
172 breakpointManager.getDb().removeBreakpoint(this);
173 callback.success(this);
174 return RelaySyncCallback.finish(syncCallback);
175 }
176
177 RemoveBreakpointParams params = new RemoveBreakpointParams(protocolId);
178
179 WipCommandCallback commandCallback;
180 if (callback == null) {
181 commandCallback = null;
182 } else {
183 commandCallback = new WipCommandCallback.Default() {
184 @Override protected void onSuccess(Success success) {
185 breakpointManager.getDb().setIdMapping(WipBreakpointImpl.this, null);
186 breakpointManager.getDb().removeBreakpoint(WipBreakpointImpl.this);
187 callback.success(WipBreakpointImpl.this);
188 }
189 @Override protected void onError(String message) {
190 callback.failure(message);
191 }
192 };
193 }
194
195 return breakpointManager.getCommandProcessor().send(params, commandCallback, syncCallback);
196 }
197
198 @Override
199 public RelayOk flush(final BreakpointCallback callback, final SyncCallback syn cCallback) {
200 final RelaySyncCallback relay = new RelaySyncCallback(syncCallback);
201
202 if (!isDirty) {
203 if (callback != null) {
204 callback.success(this);
205 }
206 return RelaySyncCallback.finish(syncCallback);
207 }
208
209 isDirty = false;
210
211 if (protocolId == null) {
212 // Breakpoint was disabled, it doesn't exist in VM, immediately start step 2.
213 return recreateBreakpointAsync(callback, relay);
214 } else {
215 // Call syncCallback if something goes wrong after we sent request.
216 final RelaySyncCallback.Guard guard = relay.newGuard();
217
218 WipCommandCallback removeCallback = new WipCommandCallback.Default() {
219 @Override
220 protected void onSuccess(Success success) {
221 setRemoteData(null, Collections.<ActualLocation>emptyList());
222 RelayOk relayOk = recreateBreakpointAsync(callback, relay);
223 guard.discharge(relayOk);
224 }
225
226 @Override
227 protected void onError(String message) {
228 throw new RuntimeException("Failed to remove breakpoint: " + message);
229 }
230 };
231
232 // Call syncCallback if something goes wrong.
233 return breakpointManager.getCommandProcessor().send(new RemoveBreakpointPa rams(protocolId),
234 removeCallback, guard.asSyncCallback());
235 }
236 }
237
238 static class ActualLocation {
239 private final String sourceId;
240 private final long lineNumber;
241 private final Long columnNumber;
242
243 ActualLocation(String sourceId, long lineNumber, Long columnNumber) {
244 this.sourceId = sourceId;
245 this.lineNumber = lineNumber;
246 this.columnNumber = columnNumber;
247 }
248
249 @Override
250 public boolean equals(Object obj) {
251 ActualLocation other = (ActualLocation) obj;
252 return this.sourceId.equals(other.sourceId) &&
253 this.lineNumber == other.lineNumber &&
254 eq(this.columnNumber, other.columnNumber);
255 }
256
257 @Override
258 public int hashCode() {
259 int column;
260 if (columnNumber == null) {
261 column = 0;
262 } else {
263 column = columnNumber.intValue();
264 }
265 return sourceId.hashCode() + 31 * (int) lineNumber + column;
266 }
267
268 @Override
269 public String toString() {
270 return "<sourceId=" + sourceId + ", line=" + lineNumber + ", column=" + co lumnNumber + ">";
271 }
272 }
273
274 private RelayOk recreateBreakpointAsync(final BreakpointCallback flushCallback ,
275 RelaySyncCallback relay) {
276
277 if (enabled) {
278 SetBreakpointCallback setCommandCallback = new SetBreakpointCallback() {
279 @Override
280 public void onSuccess(String protocolId, Collection<ActualLocation> actu alLocations) {
281 setRemoteData(protocolId, actualLocations);
282 if (flushCallback != null) {
283 flushCallback.success(WipBreakpointImpl.this);
284 }
285 }
286
287 @Override
288 public void onFailure(Exception exception) {
289 if (flushCallback != null) {
290 flushCallback.failure(exception.getMessage());
291 }
292 }
293 };
294
295 RelaySyncCallback.Guard guard = relay.newGuard();
296
297 if (condition == null) {
298 condition = "";
299 }
300 return sendSetBreakpointRequest(target, lineNumber, columnNumber, conditio n,
301 setCommandCallback, guard.asSyncCallback(),
302 breakpointManager.getCommandProcessor());
303 } else {
304 // Breakpoint is disabled, do not create it.
305 RelayOk relayOk;
306 try {
307 if (flushCallback != null) {
308 flushCallback.success(WipBreakpointImpl.this);
309 }
310 } finally {
311 relayOk = relay.finish();
312 }
313 return relayOk;
314 }
315 }
316
317 interface SetBreakpointCallback {
318 void onSuccess(String breakpointId, Collection<ActualLocation> actualLocatio ns);
319 void onFailure(Exception cause);
320 }
321
322 /**
323 * @param callback a generic callback that receives breakpoint protocol id
324 * @return
325 */
326 static RelayOk sendSetBreakpointRequest(Target target, final int lineNumber,
327 int columnNumber, final String condition,
328 final SetBreakpointCallback callback, final SyncCallback syncCallback,
329 final WipCommandProcessor commandProcessor) {
330
331 final Long columnNumberParam;
332 if (columnNumber == Breakpoint.EMPTY_VALUE) {
333 columnNumberParam = null;
334 } else {
335 columnNumberParam = Long.valueOf(columnNumber);
336 }
337
338 return target.accept(new BreakpointTypeExtension.ScriptRegExpSupport.Visitor <RelayOk>() {
339 @Override
340 public RelayOk visitScriptName(String scriptName) {
341 return sendRequest(scriptName, RequestHandler.FOR_URL);
342 }
343
344 @Override
345 public RelayOk visitRegExp(String regExp) {
346 return sendRequest(regExp, RequestHandler.FOR_REGEXP);
347 }
348
349 @Override
350 public RelayOk visitScriptId(Object scriptId) {
351 String scriptIdString = WipScriptManager.convertAlienSourceId(scriptId);
352 return sendRequest(scriptIdString, RequestHandler.FOR_ID);
353 }
354
355 @Override
356 public RelayOk visitUnknown(Target target) {
357 throw new IllegalArgumentException();
358 }
359
360 private <T, DATA, PARAMS extends WipParamsWithResponse<DATA>> RelayOk send Request(
361 T parameter, final RequestHandler<T, DATA, PARAMS> handler) {
362 PARAMS requestParams =
363 handler.createRequestParams(parameter, lineNumber, columnNumberParam , condition);
364
365 GenericCallback<DATA> wrappedCallback;
366 if (callback == null) {
367 wrappedCallback = null;
368 } else {
369 wrappedCallback = new GenericCallback<DATA>() {
370 @Override
371 public void success(DATA data) {
372 String breakpointId = handler.getBreakpointId(data);
373 Collection<LocationValue> locationValues = handler.getActualLocati ons(data);
374 List<ActualLocation> locationList =
375 new ArrayList<ActualLocation>(locationValues.size());
376 for (LocationValue value : locationValues) {
377 locationList.add(locationFromProtocol(value));
378 }
379 callback.onSuccess(breakpointId, locationList);
380 }
381
382 @Override
383 public void failure(Exception exception) {
384 callback.onFailure(exception);
385 }
386 };
387 }
388
389 return commandProcessor.send(requestParams, wrappedCallback, syncCallbac k);
390 }
391 });
392 }
393
394 private static abstract class RequestHandler<T,
395 DATA, PARAMS extends WipParamsWithResponse<DATA>> {
396
397 abstract PARAMS createRequestParams(T parameter, long lineNumber, Long colum nNumberOpt,
398 String conditionOpt);
399
400 abstract String getBreakpointId(DATA data);
401
402 abstract Collection<LocationValue> getActualLocations(DATA data);
403
404 static abstract class ForUrlOrRegExp
405 extends RequestHandler<String, SetBreakpointByUrlData, SetBreakpointByUr lParams> {
406 @Override
407 String getBreakpointId(SetBreakpointByUrlData data) {
408 return data.breakpointId();
409 }
410
411 @Override
412 Collection<LocationValue> getActualLocations(SetBreakpointByUrlData data) {
413 return data.locations();
414 }
415 }
416
417 static final ForUrlOrRegExp FOR_URL = new ForUrlOrRegExp() {
418 @Override
419 SetBreakpointByUrlParams createRequestParams(String url,
420 long lineNumber, Long columnNumber, String condition) {
421 return new SetBreakpointByUrlParams(lineNumber, url, null, columnNumber, condition);
422 }
423 };
424
425 static final ForUrlOrRegExp FOR_REGEXP = new ForUrlOrRegExp() {
426 @Override
427 SetBreakpointByUrlParams createRequestParams(String url,
428 long lineNumber, Long columnNumber, String condition) {
429 return new SetBreakpointByUrlParams(lineNumber, null, url, columnNumber, condition);
430 }
431 };
432
433 static final RequestHandler<String, SetBreakpointData, SetBreakpointParams> FOR_ID =
434 new RequestHandler<String, SetBreakpointData, SetBreakpointParams>() {
435 @Override
436 SetBreakpointParams createRequestParams(String sourceId,
437 long lineNumber, Long columnNumber, String condition) {
438 LocationParam locationParam =
439 new LocationParam(sourceId, lineNumber, columnNumber);
440 return new SetBreakpointParams(locationParam, condition);
441 }
442
443 @Override
444 String getBreakpointId(SetBreakpointData data) {
445 return data.breakpointId();
446 }
447
448 @Override
449 Collection<LocationValue> getActualLocations(SetBreakpointData data) {
450 return Collections.singletonList(data.actualLocation());
451 }
452 };
453 }
454
455 private static ActualLocation locationFromProtocol(LocationValue locationValue ) {
456 return new ActualLocation(locationValue.scriptId(), locationValue.lineNumber (),
457 locationValue.columnNumber());
458 }
459
460 private static <T> boolean eq(T left, T right) {
461 return left == right || (left != null && left.equals(right));
462 }
463 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698