Sat, 07 Nov 2020 10:30:02 +0800
Added tag mips-jdk8u275-b01 for changeset fdbe50121f48
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.handler;
28 import com.sun.xml.internal.ws.api.WSBinding;
30 import javax.xml.ws.ProtocolException;
31 import javax.xml.ws.handler.Handler;
32 import javax.xml.ws.handler.MessageContext;
33 import java.util.ArrayList;
34 import java.util.List;
35 import java.util.logging.Level;
36 import java.util.logging.Logger;
38 /**
39 * @author WS Development Team
40 */
41 abstract class HandlerProcessor<C extends MessageUpdatableContext> {
43 boolean isClient;
44 static final Logger logger = Logger.getLogger(
45 com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".handler");
47 // need request or response for Handle interface
48 public enum RequestOrResponse {
49 REQUEST, RESPONSE }
51 public enum Direction {
52 OUTBOUND, INBOUND }
54 private List<? extends Handler> handlers; // may be logical/soap mixed
56 WSBinding binding;
57 private int index = -1;
58 private HandlerTube owner;
60 /**
61 * The handlers that are passed in will be sorted into
62 * logical and soap handlers. During this sorting, the
63 * understood headers are also obtained from any soap
64 * handlers.
65 *
66 * @param chain A list of handler objects, which can
67 * be protocol or logical handlers.
68 */
69 protected HandlerProcessor(HandlerTube owner, WSBinding binding, List<? extends Handler> chain) {
70 this.owner = owner;
71 if (chain == null) { // should only happen in testing
72 chain = new ArrayList<Handler>();
73 }
74 handlers = chain;
75 this.binding = binding;
76 }
78 /**
79 * Gives index of the handler in the chain to know what handlers in the chain
80 * are invoked
81 */
82 int getIndex() {
83 return index;
84 }
86 /**
87 * This is called when a handler returns false or throws a RuntimeException
88 */
89 void setIndex(int i) {
90 index = i;
91 }
93 /**
94 * TODO: Just putting thoughts,
95 * Current contract: This is Called during Request Processing.
96 * return true, if all handlers in the chain return true
97 * Current Pipe can call nextPipe.process();
98 * return false, One of the handlers has returned false or thrown a
99 * RuntimeException. Remedy Actions taken:
100 * 1) In this case, The processor will setIndex()to track what
101 * handlers are invoked until that point.
102 * 2) Previously invoked handlers are again invoked (handleMessage()
103 * or handleFault()) to take remedy action.
104 * CurrentPipe should NOT call nextPipe.process()
105 * While closing handlers, check getIndex() to get the invoked
106 * handlers.
107 * @throws RuntimeException this happens when a RuntimeException occurs during
108 * handleMessage during Request processing or
109 * during remedy action 2)
110 * CurrentPipe should NOT call nextPipe.process() and throw the
111 * exception to the previous Pipe
112 * While closing handlers, check getIndex() to get the invoked
113 * handlers.
114 */
115 public boolean callHandlersRequest(Direction direction,
116 C context,
117 boolean responseExpected) {
118 setDirection(direction, context);
119 boolean result;
120 // call handlers
121 try {
122 if (direction == Direction.OUTBOUND) {
123 result = callHandleMessage(context, 0, handlers.size() - 1);
124 } else {
125 result = callHandleMessage(context, handlers.size() - 1, 0);
126 }
127 } catch (ProtocolException pe) {
128 logger.log(Level.FINER, "exception in handler chain", pe);
129 if (responseExpected) {
130 //insert fault message if its not a fault message
131 insertFaultMessage(context, pe);
132 // reverse direction
133 reverseDirection(direction, context);
134 //Set handleFault so that cousinTube is aware of fault
135 setHandleFaultProperty();
136 // call handle fault
137 if (direction == Direction.OUTBOUND) {
138 callHandleFault(context, getIndex() - 1, 0);
139 } else {
140 callHandleFault(context, getIndex() + 1, handlers.size() - 1);
141 }
142 return false;
143 }
144 throw pe;
145 } catch (RuntimeException re) {
146 logger.log(Level.FINER, "exception in handler chain", re);
147 throw re;
148 }
150 if (!result) {
151 if (responseExpected) {
152 // reverse direction
153 reverseDirection(direction, context);
154 // call handle message
155 if (direction == Direction.OUTBOUND) {
156 callHandleMessageReverse(context, getIndex() - 1, 0);
157 } else {
158 callHandleMessageReverse(context, getIndex() + 1, handlers.size() - 1);
159 }
160 } else {
161 // Set handleFalse so that cousinTube is aware of false processing
162 // Oneway, dispatch the message
163 // cousinTube should n't call handleMessage() anymore.
164 setHandleFalseProperty();
165 }
166 return false;
167 }
169 return result;
170 }
173 /**
174 * TODO: Just putting thoughts,
175 * Current contract: This is Called during Response Processing.
176 * Runs all handlers until handle returns false or throws a RuntimeException
177 * CurrentPipe should close all the handlers in the chain.
178 * throw RuntimeException, this happens when a RuntimeException occurs during
179 * normal Response processing or remedy action 2) taken
180 * during callHandlersRequest().
181 * CurrentPipe should close all the handlers in the chain. *
182 */
183 public void callHandlersResponse(Direction direction,
184 C context, boolean isFault) {
185 setDirection(direction, context);
186 try {
187 if (isFault) {
188 // call handleFault on handlers
189 if (direction == Direction.OUTBOUND) {
190 callHandleFault(context, 0, handlers.size() - 1);
191 } else {
192 callHandleFault(context, handlers.size() - 1, 0);
193 }
194 } else {
195 // call handleMessage on handlers
196 if (direction == Direction.OUTBOUND) {
197 callHandleMessageReverse(context, 0, handlers.size() - 1);
198 } else {
199 callHandleMessageReverse(context, handlers.size() - 1, 0);
200 }
201 }
202 } catch (RuntimeException re) {
203 logger.log(Level.FINER, "exception in handler chain", re);
204 throw re;
205 }
206 }
209 /**
210 * Reverses the Message Direction.
211 * MessageContext.MESSAGE_OUTBOUND_PROPERTY is changed.
212 */
213 private void reverseDirection(Direction origDirection, C context) {
214 if (origDirection == Direction.OUTBOUND) {
215 context.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, false);
216 } else {
217 context.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, true);
218 }
219 }
221 /**
222 * Sets the Message Direction.
223 * MessageContext.MESSAGE_OUTBOUND_PROPERTY is changed.
224 */
225 private void setDirection(Direction direction, C context) {
226 if (direction == Direction.OUTBOUND) {
227 context.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, true);
228 } else {
229 context.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, false);
230 }
231 }
233 /**
234 * When this property is set HandlerPipes can call handleFault() on the
235 * message
236 */
237 private void setHandleFaultProperty() {
238 owner.setHandleFault();
239 }
241 /**
242 * When this property is set HandlerPipes will not call
243 * handleMessage() during Response processing.
244 */
245 private void setHandleFalseProperty() {
246 owner.setHandleFalse();
247 }
249 /**
250 * When a ProtocolException is thrown, this is called.
251 * If it's XML/HTTP Binding, clear the the message
252 * If its SOAP/HTTP Binding, put right SOAP Fault version
253 */
254 abstract void insertFaultMessage(C context,
255 ProtocolException exception);
257 /*
258 * Calls handleMessage on the handlers. Indices are
259 * inclusive. Exceptions get passed up the chain, and an
260 * exception or return of 'false' ends processing.
261 */
262 private boolean callHandleMessage(C context, int start, int end) {
263 /* Do we need this check?
264 if (handlers.isEmpty() ||
265 start == -1 ||
266 start == handlers.size()) {
267 return false;
268 }
269 */
270 int i = start;
271 try {
272 if (start > end) {
273 while (i >= end) {
274 if (!handlers.get(i).handleMessage(context)) {
275 setIndex(i);
276 return false;
277 }
278 i--;
279 }
280 } else {
281 while (i <= end) {
282 if (!handlers.get(i).handleMessage(context)) {
283 setIndex(i);
284 return false;
285 }
286 i++;
287 }
288 }
289 } catch (RuntimeException e) {
290 setIndex(i);
291 throw e;
292 }
293 return true;
294 }
296 /*
297 * Calls handleMessage on the handlers. Indices are
298 * inclusive. Exceptions get passed up the chain, and an
299 * exception (or)
300 * return of 'false' calls addHandleFalseProperty(context) and
301 * ends processing.
302 * setIndex() is not called.
303 *
304 */
305 private boolean callHandleMessageReverse(C context, int start, int end) {
307 if (handlers.isEmpty() ||
308 start == -1 ||
309 start == handlers.size()) {
310 return false;
311 }
313 int i = start;
315 if (start > end) {
316 while (i >= end) {
317 if (!handlers.get(i).handleMessage(context)) {
318 // Set handleFalse so that cousinTube is aware of false processing
319 setHandleFalseProperty();
320 return false;
321 }
322 i--;
323 }
324 } else {
325 while (i <= end) {
326 if (!handlers.get(i).handleMessage(context)) {
327 // Set handleFalse so that cousinTube is aware of false processing
328 setHandleFalseProperty();
329 return false;
330 }
331 i++;
332 }
333 }
334 return true;
335 }
337 /*
338 * Calls handleFault on the handlers. Indices are
339 * inclusive. Exceptions get passed up the chain, and an
340 * exception or return of 'false' ends processing.
341 */
343 private boolean callHandleFault(C context, int start, int end) {
345 if (handlers.isEmpty() ||
346 start == -1 ||
347 start == handlers.size()) {
348 return false;
349 }
351 int i = start;
352 if (start > end) {
353 try {
354 while (i >= end) {
355 if (!handlers.get(i).handleFault(context)) {
356 return false;
357 }
358 i--;
359 }
360 } catch (RuntimeException re) {
361 logger.log(Level.FINER,
362 "exception in handler chain", re);
363 throw re;
364 }
365 } else {
366 try {
367 while (i <= end) {
368 if (!handlers.get(i).handleFault(context)) {
369 return false;
370 }
371 i++;
372 }
373 } catch (RuntimeException re) {
374 logger.log(Level.FINER,
375 "exception in handler chain", re);
376 throw re;
377 }
378 }
379 return true;
380 }
382 /**
383 * Calls close on the handlers from the starting
384 * index through the ending index (inclusive). Made indices
385 * inclusive to allow both directions more easily.
386 */
387 void closeHandlers(MessageContext context, int start, int end) {
388 if (handlers.isEmpty() ||
389 start == -1) {
390 return;
391 }
392 if (start > end) {
393 for (int i = start; i >= end; i--) {
394 try {
395 handlers.get(i).close(context);
396 } catch (RuntimeException re) {
397 logger.log(Level.INFO,
398 "Exception ignored during close", re);
399 }
400 }
401 } else {
402 for (int i = start; i <= end; i++) {
403 try {
404 handlers.get(i).close(context);
405 } catch (RuntimeException re) {
406 logger.log(Level.INFO,
407 "Exception ignored during close", re);
408 }
409 }
410 }
411 }
412 }