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

Side by Side Diff: plugins/org.chromium.sdk.wipbackend.wk120709/src/org/chromium/sdk/internal/wip/WipRelayRunner.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 org.chromium.sdk.RelayOk;
8 import org.chromium.sdk.SyncCallback;
9 import org.chromium.sdk.internal.wip.protocol.input.WipCommandResponse;
10 import org.chromium.sdk.internal.wip.protocol.output.WipParams;
11 import org.chromium.sdk.internal.wip.protocol.output.WipParamsWithResponse;
12 import org.chromium.sdk.util.GenericCallback;
13 import org.chromium.sdk.util.RelaySyncCallback;
14
15 /**
16 * A utility class that helps running a chain of asynchronous commands in a safe manner.
17 * 'Safe' here means that the client will get {@link SyncCallback} called in the end
18 * in any scenario.
19 * <p>
20 * The class helps reformat control sequence: instead of being callback-driven, the program
21 * becomes step-driven. Each step defines a request being sent, the way a respon se is processed
22 * and a link to the next step.
23 * <p>
24 * The class is bound to {@link WipCommandProcessor}.
25 */
26 public class WipRelayRunner {
27
28 /**
29 * The main abstraction of {@link WipRelayRunner}. A particular relay consists is a chain
30 * of steps. Each step returns a next step except for the 'final' step
31 * (see {@link WipRelayRunner#createFinalStep(Object)}).
32 * <p>This type is essentially an algebraic data type.
33 *
34 * @param <RES> a type that the entire relay should return
35 */
36 interface Step<RES> {
37 <R> R accept(Visitor<R, RES> visitor);
38
39 interface Visitor<R, RES> {
40 R visitFinal(RES finalResult);
41 R visitSend(SendStepSimple<RES> sendStep);
42 <DATA> R visitSend(SendStepWithResponse<DATA, RES> sendStep);
43 }
44 }
45
46 /**
47 * Creates a final step that simply holds a result.
48 */
49 public static <RES> Step<RES> createFinalStep(final RES finalResult) {
50 return new Step<RES>() {
51 @Override
52 public <R> R accept(Visitor<R, RES> visitor) {
53 return visitor.visitFinal(finalResult);
54 }
55 };
56 }
57
58 /**
59 * A base class for 'send' step that sends a request and processes its respons e.
60 * @param <RES> a type that the entire relay should return
61 */
62 public static abstract class SendStepSimple<RES> implements Step<RES> {
63 public abstract WipParams getParams();
64
65 /**
66 * Handles normal response and returns a next step (or throws {@link Process Exception}).
67 * The response itself contains no data, so there's no such parameter.
68 */
69 public abstract Step<RES> processResponse() throws ProcessException;
70
71 /**
72 * Optionally wraps the cause with a more high-level exception. Must return cause by default.
73 * @return not null
74 */
75 public abstract Exception processFailure(Exception cause);
76
77 @Override public final <R> R accept(Visitor<R, RES> visitor) {
78 return visitor.visitSend(this);
79 }
80 }
81
82 public static abstract class SendStepWithResponse<DATA, RES> implements Step<R ES> {
83 public abstract WipParamsWithResponse<DATA> getParams();
84
85 /**
86 * Handles normal response and returns a next step (or throws {@link Process Exception}).
87 */
88 public abstract Step<RES> processResponse(DATA response) throws ProcessExcep tion;
89
90 /**
91 * Optionally wraps the cause with a more high-level exception. Must return cause by default.
92 * @return not null
93 */
94 public abstract Exception processFailure(Exception cause);
95
96 @Override public final <R> R accept(Visitor<R, RES> visitor) {
97 return visitor.visitSend(this);
98 }
99 }
100
101 /**
102 * An exception that step can throw if response cannot be processed normally. It aborts the relay
103 * and gets passed to user callback.
104 */
105 public static class ProcessException extends Exception {
106 public ProcessException() {
107 }
108 public ProcessException(String message, Throwable cause) {
109 super(message, cause);
110 }
111 public ProcessException(String message) {
112 super(message);
113 }
114 public ProcessException(Throwable cause) {
115 super(cause);
116 }
117 }
118
119 /**
120 * Runs a relay defined by a chain of steps.
121 * @param <RES> return type of the entire relay
122 * @param firstStep a first step that defines the entire relay
123 * @param callback
124 * @param relaySyncCallback a {@link SyncCallback} wrapped as {@link RelaySync Callback}
125 */
126 public static <RES> RelayOk run(final WipCommandProcessor commandProcessor, St ep<RES> firstStep,
127 final GenericCallback<RES> callback, final RelaySyncCallback relaySyncCall back) {
128
129 return firstStep.accept(new Step.Visitor<RelayOk, RES>() {
130 @Override
131 public RelayOk visitFinal(RES finalResult) {
132 if (callback != null) {
133 callback.success(finalResult);
134 }
135 return relaySyncCallback.finish();
136 }
137
138 @Override
139 public RelayOk visitSend(final SendStepSimple<RES> sendStep) {
140 final RelaySyncCallback.Guard guard = relaySyncCallback.newGuard();
141
142 WipCommandCallback sendCallback = new WipCommandCallback() {
143 @Override
144 public void messageReceived(WipCommandResponse response) {
145 Step<RES> processResult;
146 try {
147 processResult = sendStep.processResponse();
148 } catch (ProcessException e) {
149 if (callback != null) {
150 callback.failure(e);
151 }
152 // Todo: consider throwing e.
153 return;
154 }
155 RelayOk relayOk = run(commandProcessor, processResult, callback, gua rd.getRelay());
156 guard.discharge(relayOk);
157 }
158 @Override
159 public void failure(String message) {
160 if (callback != null) {
161 callback.failure(sendStep.processFailure(new Exception(message)));
162 }
163 }
164 };
165
166 return commandProcessor.send(sendStep.getParams(), sendCallback, guard.a sSyncCallback());
167 }
168
169 @Override
170 public <RESPONSE> RelayOk visitSend(final SendStepWithResponse<RESPONSE, R ES> sendStep) {
171 final RelaySyncCallback.Guard guard = relaySyncCallback.newGuard();
172
173 GenericCallback<RESPONSE> sendCallback = new GenericCallback<RESPONSE>() {
174 @Override
175 public void success(RESPONSE response) {
176 Step<RES> processResult;
177 try {
178 processResult = sendStep.processResponse(response);
179 } catch (ProcessException e) {
180 if (callback != null) {
181 callback.failure(e);
182 }
183 // Todo: consider throwing e.
184 return;
185 }
186 RelayOk relayOk = run(commandProcessor, processResult, callback, gua rd.getRelay());
187 guard.discharge(relayOk);
188 }
189
190 @Override
191 public void failure(Exception exception) {
192 if (callback != null) {
193 callback.failure(sendStep.processFailure(exception));
194 }
195 }
196 };
197
198 return commandProcessor.send(sendStep.getParams(), sendCallback, guard.a sSyncCallback());
199 }
200 });
201 }
202 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698