1 /* 2 * Copyright (c) 1997, 2010, 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 */ 25 26 package com.sun.xml.internal.ws.api.pipe; 27 28 import com.sun.xml.internal.ws.api.message.Packet; 29 30 /** 31 * Indicates what shall happen after {@link Tube#processRequest(Packet)} or 32 * {@link Tube#processResponse(Packet)} returns. 33 * 34 * <p> 35 * To allow reuse of this object, this class is mutable. 36 * 37 * @author Kohsuke Kawaguchi 38 */ 39 public final class NextAction { 40 int kind; 41 Tube next; 42 Packet packet; 43 /** 44 * Really either {@link RuntimeException} or {@link Error}. 45 */ 46 Throwable throwable; 47 48 // public enum Kind { INVOKE, INVOKE_AND_FORGET, RETURN, SUSPEND } 49 50 static final int INVOKE = 0; 51 static final int INVOKE_AND_FORGET = 1; 52 static final int RETURN = 2; 53 static final int THROW = 3; 54 static final int SUSPEND = 4; 55 // Used to abort processResponse chain if a fatal exception is encountered 56 static final int THROW_ABORT_RESPONSE = 5; 57 // Used to abort processResponse chain if a response should be aborted 58 static final int ABORT_RESPONSE = 6; 59 // Used to switch a tubeline from synchronous to asynchronous execution 60 // with respect to the thread that started this tubeline. 61 static final int INVOKE_ASYNC = 7; 62 63 private void set(int k, Tube v, Packet p, Throwable t) { 64 this.kind = k; 65 this.next = v; 66 this.packet = p; 67 this.throwable = t; 68 } 69 70 /** 71 * Indicates that the next action should be to 72 * invoke the next tube's {@link Tube#processRequest(Packet)}, 73 * then later invoke the current tube's {@link Tube#processResponse(Packet)} 74 * with the response packet. 75 */ 76 public void invoke(Tube next, Packet p) { 77 set(INVOKE, next, p, null); 78 } 79 80 /** 81 * Indicates that the next action should be to 82 * invoke the next tube's {@link Tube#processRequest(Packet)}, 83 * but the current tube doesn't want to receive the response packet to 84 * its {@link Tube#processResponse(Packet)}. 85 */ 86 public void invokeAndForget(Tube next, Packet p) { 87 set(INVOKE_AND_FORGET, next, p, null); 88 } 89 90 /** 91 * Indicates that the next action is to flip the processing direction 92 * and starts response processing. 93 */ 94 public void returnWith( Packet response ) { 95 set(RETURN, null, response, null); 96 } 97 98 /** 99 * Indicates that the next action is to flip the processing direction 100 * and starts exception processing. 101 * 102 * @param t 103 * Either {@link RuntimeException} or {@link Error}, but defined to 104 * take {@link Throwable} because {@link Tube#processException(Throwable)} 105 * takes {@link Throwable}. 106 */ 107 public void throwException(Throwable t) { 108 assert t instanceof RuntimeException || t instanceof Error; 109 set(THROW,null,null,t); 110 } 111 112 /** 113 * Indicates that the next action is to abort the processResponse chain 114 * because of an exception. How that exception is processed is not 115 * defined. 116 * 117 * @param t 118 * Either {@link RuntimeException} or {@link Error} 119 */ 120 public void throwExceptionAbortResponse(Throwable t) { 121 set(THROW_ABORT_RESPONSE,null,null,t); 122 } 123 124 /** 125 * Indicates that the next action is to abort the processResponse chain 126 * because of some non-exception condition. 127 * 128 * @param response The response that is being aborted 129 */ 130 public void abortResponse(Packet response) { 131 set(ABORT_RESPONSE,null,response,null); 132 } 133 134 /** 135 * Indicates that the next action is to invoke the next tube in the 136 * tubeline async from the thread that started the tubeline. Only fibers 137 * that were started using startSync should use this next action kind. 138 * @param next The next tube in the tubeline 139 * @param p The request to pass to the next tube 140 */ 141 public void invokeAsync(Tube next, Packet p) { 142 set(INVOKE_ASYNC,next,p,null); 143 } 144 145 /** 146 * Indicates that the fiber should be suspended. 147 * Once {@link Fiber#resume(Packet) resumed}, return the response processing. 148 */ 149 public void suspend() { 150 set(SUSPEND, null, null, null); 151 } 152 153 /** 154 * Indicates that the fiber should be suspended. 155 * Once {@link Fiber#resume(Packet) resumed}, resume with the 156 * {@link Tube#processRequest(Packet)} on the given next tube. 157 */ 158 public void suspend(Tube next) { 159 set(SUSPEND, next, null, null); 160 } 161 162 /** Returns the next tube 163 * @return Next tube 164 */ 165 public Tube getNext() { 166 return next; 167 } 168 169 /** Sets the next tube 170 * @param next Next tube 171 */ 172 public void setNext(Tube next) { 173 this.next = next; 174 } 175 176 /** 177 * Returns the last Packet 178 * @return Packet 179 */ 180 public Packet getPacket() { 181 return packet; 182 } 183 184 /** 185 * Returns the Throwable generated by the last Tube 186 * @return the Throwable 187 */ 188 public Throwable getThrowable() { 189 return throwable; 190 } 191 192 /** 193 * Dumps the contents to assist debugging. 194 */ 195 @Override 196 public String toString() { 197 StringBuilder buf = new StringBuilder(); 198 buf.append(super.toString()).append(" ["); 199 buf.append("kind=").append(getKindString()).append(','); 200 buf.append("next=").append(next).append(','); 201 buf.append("packet=").append(packet != null ? packet.toShortString() : null).append(','); 202 buf.append("throwable=").append(throwable).append(']'); 203 return buf.toString(); 204 } 205 206 /** 207 * Returns {@link #kind} in a human readable string, to assist debugging. 208 */ 209 public String getKindString() { 210 switch(kind) { 211 case INVOKE: return "INVOKE"; 212 case INVOKE_AND_FORGET: return "INVOKE_AND_FORGET"; 213 case RETURN: return "RETURN"; 214 case THROW: return "THROW"; 215 case SUSPEND: return "SUSPEND"; 216 case THROW_ABORT_RESPONSE: return "THROW_ABORT_RESPONSE"; 217 case ABORT_RESPONSE: return "ABORT_RESPONSE"; 218 case INVOKE_ASYNC: return "INVOKE_ASYNC"; 219 default: throw new AssertionError(kind); 220 } 221 } 222 }