Thu, 31 Aug 2017 15:18:52 +0800
merge
1 /*
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.xml.internal.ws.api.pipe;
28 import com.sun.xml.internal.ws.api.message.Packet;
29 import java.util.concurrent.Executor;
31 /**
32 * Indicates what shall happen after {@link Tube#processRequest(Packet)} or
33 * {@link Tube#processResponse(Packet)} returns.
34 *
35 * <p>
36 * To allow reuse of this object, this class is mutable.
37 *
38 * @author Kohsuke Kawaguchi
39 */
40 public final class NextAction {
41 int kind;
42 Tube next;
43 Packet packet;
44 /**
45 * Really either {@link RuntimeException} or {@link Error}.
46 */
47 Throwable throwable;
48 Runnable onExitRunnable;
50 // public enum Kind { INVOKE, INVOKE_AND_FORGET, RETURN, SUSPEND }
52 static final int INVOKE = 0;
53 static final int INVOKE_AND_FORGET = 1;
54 static final int RETURN = 2;
55 static final int THROW = 3;
56 static final int SUSPEND = 4;
57 // Used to abort processResponse chain if a fatal exception is encountered
58 static final int THROW_ABORT_RESPONSE = 5;
59 // Used to abort processResponse chain if a response should be aborted
60 static final int ABORT_RESPONSE = 6;
61 // Used to switch a tubeline from synchronous to asynchronous execution
62 // with respect to the thread that started this tubeline.
63 static final int INVOKE_ASYNC = 7;
65 private void set(int k, Tube v, Packet p, Throwable t) {
66 this.kind = k;
67 this.next = v;
68 this.packet = p;
69 this.throwable = t;
70 }
72 /**
73 * Indicates that the next action should be to
74 * invoke the next tube's {@link Tube#processRequest(Packet)},
75 * then later invoke the current tube's {@link Tube#processResponse(Packet)}
76 * with the response packet.
77 */
78 public void invoke(Tube next, Packet p) {
79 set(INVOKE, next, p, null);
80 }
82 /**
83 * Indicates that the next action should be to
84 * invoke the next tube's {@link Tube#processRequest(Packet)},
85 * but the current tube doesn't want to receive the response packet to
86 * its {@link Tube#processResponse(Packet)}.
87 */
88 public void invokeAndForget(Tube next, Packet p) {
89 set(INVOKE_AND_FORGET, next, p, null);
90 }
92 /**
93 * Indicates that the next action is to flip the processing direction
94 * and starts response processing.
95 */
96 public void returnWith( Packet response ) {
97 set(RETURN, null, response, null);
98 }
100 /**
101 * Indicates that the next action is to flip the processing direction
102 * and starts exception processing, but with the indicated context.
103 *
104 * @param t
105 * Either {@link RuntimeException} or {@link Error}, but defined to
106 * take {@link Throwable} because {@link Tube#processException(Throwable)}
107 * takes {@link Throwable}.
108 */
109 public void throwException( Packet response, Throwable t ) {
110 // Use of RETURN is correct -- Fiber processing does not set packet for type of THROW
111 set(RETURN, null, response, t);
112 }
114 /**
115 * Indicates that the next action is to flip the processing direction
116 * and starts exception processing.
117 *
118 * @param t
119 * Either {@link RuntimeException} or {@link Error}, but defined to
120 * take {@link Throwable} because {@link Tube#processException(Throwable)}
121 * takes {@link Throwable}.
122 */
123 public void throwException(Throwable t) {
124 assert t instanceof RuntimeException || t instanceof Error;
125 set(THROW,null,null,t);
126 }
128 /**
129 * Indicates that the next action is to abort the processResponse chain
130 * because of an exception. How that exception is processed is not
131 * defined.
132 *
133 * @param t
134 * Either {@link RuntimeException} or {@link Error}
135 */
136 public void throwExceptionAbortResponse(Throwable t) {
137 set(THROW_ABORT_RESPONSE,null,null,t);
138 }
140 /**
141 * Indicates that the next action is to abort the processResponse chain
142 * because of some non-exception condition.
143 *
144 * @param response The response that is being aborted
145 */
146 public void abortResponse(Packet response) {
147 set(ABORT_RESPONSE,null,response,null);
148 }
150 /**
151 * Indicates that the next action is to invoke the next tube in the
152 * tubeline async from the thread that started the tubeline. Only fibers
153 * that were started using startSync should use this next action kind.
154 * @param next The next tube in the tubeline
155 * @param p The request to pass to the next tube
156 */
157 public void invokeAsync(Tube next, Packet p) {
158 set(INVOKE_ASYNC,next,p,null);
159 }
161 /**
162 * Indicates that the fiber should be suspended.
163 * Once {@link Fiber#resume(Packet) resumed}, return the response processing.
164 * @deprecated Use variants that pass {@link Runnable}
165 */
166 public void suspend() {
167 suspend(null, null);
168 }
170 /**
171 * Indicates that the fiber should be suspended. Once the current {@link Thread}
172 * exits the fiber's control loop, the onExitRunnable will be invoked. This {@link Runnable}
173 * may call {@link Fiber#resume(Packet)}; however it is still guaranteed that the current
174 * Thread will return control, therefore, further processing will be handled on a {@link Thread}
175 * from the {@link Executor}. For synchronous cases, the Thread invoking this fiber cannot return
176 * until fiber processing is complete; therefore, the guarantee is only that the onExitRunnable
177 * will be invoked prior to completing the suspension.
178 * @since 2.2.7
179 */
180 public void suspend(Runnable onExitRunnable) {
181 suspend(null, onExitRunnable);
182 }
184 /**
185 * Indicates that the fiber should be suspended.
186 * Once {@link Fiber#resume(Packet) resumed}, resume with the
187 * {@link Tube#processRequest(Packet)} on the given next tube.
188 * @deprecated Use variants that pass {@link Runnable}
189 */
190 public void suspend(Tube next) {
191 suspend(next, null);
192 }
194 /**
195 * Indicates that the fiber should be suspended. Once the current {@link Thread}
196 * exits the fiber's control loop, the onExitRunnable will be invoked. This {@link Runnable}
197 * may call {@link Fiber#resume(Packet)}; however it is still guaranteed that the current
198 * fiber will return control, therefore, further processing will be handled on a {@link Thread}
199 * from the {@link Executor}. For synchronous cases, the Thread invoking this fiber cannot return
200 * until fiber processing is complete; therefore, the guarantee is only that the onExitRunnable
201 * will be invoked prior to completing the suspension.
202 * <p>
203 * Once {@link Fiber#resume(Packet) resumed}, resume with the
204 * {@link Tube#processRequest(Packet)} on the given next tube.
205 * @since 2.2.7
206 */
207 public void suspend(Tube next, Runnable onExitRunnable) {
208 set(SUSPEND, next, null, null);
209 this.onExitRunnable = onExitRunnable;
210 }
212 /** Returns the next tube
213 * @return Next tube
214 */
215 public Tube getNext() {
216 return next;
217 }
219 /** Sets the next tube
220 * @param next Next tube
221 */
222 public void setNext(Tube next) {
223 this.next = next;
224 }
226 /**
227 * Returns the last Packet
228 * @return Packet
229 */
230 public Packet getPacket() {
231 return packet;
232 }
234 /**
235 * Returns the Throwable generated by the last Tube
236 * @return the Throwable
237 */
238 public Throwable getThrowable() {
239 return throwable;
240 }
242 /**
243 * Dumps the contents to assist debugging.
244 */
245 @Override
246 public String toString() {
247 StringBuilder buf = new StringBuilder();
248 buf.append(super.toString()).append(" [");
249 buf.append("kind=").append(getKindString()).append(',');
250 buf.append("next=").append(next).append(',');
251 buf.append("packet=").append(packet != null ? packet.toShortString() : null).append(',');
252 buf.append("throwable=").append(throwable).append(']');
253 return buf.toString();
254 }
256 /**
257 * Returns {@link #kind} in a human readable string, to assist debugging.
258 */
259 public String getKindString() {
260 switch(kind) {
261 case INVOKE: return "INVOKE";
262 case INVOKE_AND_FORGET: return "INVOKE_AND_FORGET";
263 case RETURN: return "RETURN";
264 case THROW: return "THROW";
265 case SUSPEND: return "SUSPEND";
266 case THROW_ABORT_RESPONSE: return "THROW_ABORT_RESPONSE";
267 case ABORT_RESPONSE: return "ABORT_RESPONSE";
268 case INVOKE_ASYNC: return "INVOKE_ASYNC";
269 default: throw new AssertionError(kind);
270 }
271 }
272 }