src/share/jaxws_classes/com/sun/xml/internal/ws/server/sei/TieHandler.java

Fri, 04 Oct 2013 16:21:34 +0100

author
mkos
date
Fri, 04 Oct 2013 16:21:34 +0100
changeset 408
b0610cd08440
parent 368
0989ad8c0860
child 637
9c07ef4934dd
permissions
-rw-r--r--

8025054: Update JAX-WS RI integration to 2.2.9-b130926.1035
Reviewed-by: chegar

ohair@286 1 /*
alanb@368 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
ohair@286 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ohair@286 4 *
ohair@286 5 * This code is free software; you can redistribute it and/or modify it
ohair@286 6 * under the terms of the GNU General Public License version 2 only, as
ohair@286 7 * published by the Free Software Foundation. Oracle designates this
ohair@286 8 * particular file as subject to the "Classpath" exception as provided
ohair@286 9 * by Oracle in the LICENSE file that accompanied this code.
ohair@286 10 *
ohair@286 11 * This code is distributed in the hope that it will be useful, but WITHOUT
ohair@286 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ohair@286 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ohair@286 14 * version 2 for more details (a copy is included in the LICENSE file that
ohair@286 15 * accompanied this code).
ohair@286 16 *
ohair@286 17 * You should have received a copy of the GNU General Public License version
ohair@286 18 * 2 along with this work; if not, write to the Free Software Foundation,
ohair@286 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ohair@286 20 *
ohair@286 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@286 22 * or visit www.oracle.com if you need additional information or have any
ohair@286 23 * questions.
ohair@286 24 */
ohair@286 25
ohair@286 26 package com.sun.xml.internal.ws.server.sei;
ohair@286 27
alanb@368 28 import com.oracle.webservices.internal.api.databinding.JavaCallInfo;
ohair@286 29 import com.sun.xml.internal.ws.api.SOAPVersion;
ohair@286 30 import com.sun.xml.internal.ws.api.WSBinding;
ohair@286 31 import com.sun.xml.internal.ws.api.databinding.EndpointCallBridge;
ohair@286 32 import com.sun.xml.internal.ws.api.message.Message;
alanb@368 33 import com.sun.xml.internal.ws.api.message.MessageContextFactory;
ohair@286 34 import com.sun.xml.internal.ws.api.message.Packet;
ohair@286 35 import com.sun.xml.internal.ws.api.model.JavaMethod;
ohair@286 36 import com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
ohair@286 37 import com.sun.xml.internal.ws.message.jaxb.JAXBMessage;
ohair@286 38 import com.sun.xml.internal.ws.model.JavaMethodImpl;
ohair@286 39 import com.sun.xml.internal.ws.model.ParameterImpl;
ohair@286 40 import com.sun.xml.internal.ws.model.WrapperParameter;
ohair@286 41 import com.sun.xml.internal.ws.wsdl.DispatchException;
ohair@286 42
ohair@286 43 import javax.jws.WebParam.Mode;
ohair@286 44 import javax.xml.bind.JAXBException;
ohair@286 45 import javax.xml.stream.XMLStreamException;
ohair@286 46 import javax.xml.ws.Holder;
ohair@286 47 import javax.xml.ws.ProtocolException;
ohair@286 48 import javax.xml.ws.WebServiceException;
ohair@286 49 import java.lang.reflect.InvocationTargetException;
ohair@286 50 import java.lang.reflect.Method;
ohair@286 51 import java.util.ArrayList;
ohair@286 52 import java.util.List;
ohair@286 53 import java.util.logging.Level;
ohair@286 54 import java.util.logging.Logger;
ohair@286 55
ohair@286 56 /**
ohair@286 57 *
ohair@286 58 * <p>
ohair@286 59 * This class mainly performs the following two tasks:
ohair@286 60 * <ol>
alanb@368 61 * <li>Takes a {@link Message} that represents a request,
ohair@286 62 * and extracts the arguments (and updates {@link Holder}s.)
ohair@286 63 * <li>Accepts return value and {@link Holder} arguments for a Java method,
ohair@286 64 * and creates {@link JAXBMessage} that represents a response message.
ohair@286 65 * </ol>
ohair@286 66 *
ohair@286 67 * <h2>Creating {@link JAXBMessage}</h2>
ohair@286 68 * <p>
ohair@286 69 * At the construction time, we prepare {@link EndpointArgumentsBuilder} that knows how to create endpoint {@link Method}
ohair@286 70 * invocation arguments.
ohair@286 71 * we also prepare {@link EndpointResponseMessageBuilder} and {@link MessageFiller}s
ohair@286 72 * that know how to move arguments into a {@link Message}.
ohair@286 73 * Some arguments go to the payload, some go to headers, still others go to attachments.
ohair@286 74 *
ohair@286 75 * @author Jitendra Kotamraju
ohair@286 76 * @author shih-chang.chen@oracle.com
ohair@286 77 * Refactored from EndpointMethodHandler
ohair@286 78 */
ohair@286 79 final public class TieHandler implements EndpointCallBridge {
ohair@286 80
ohair@286 81 private final SOAPVersion soapVersion;
ohair@286 82 private final Method method;
ohair@286 83 private final int noOfArgs;
ohair@286 84 private final JavaMethodImpl javaMethodModel;
ohair@286 85
ohair@286 86 private final Boolean isOneWay;
ohair@286 87
ohair@286 88 // Converts {@link Message} --> Object[]
ohair@286 89 private final EndpointArgumentsBuilder argumentsBuilder;
ohair@286 90
ohair@286 91 // these objects together create a response message from method parameters
ohair@286 92 private final EndpointResponseMessageBuilder bodyBuilder;
ohair@286 93 private final MessageFiller[] outFillers;
alanb@368 94 protected MessageContextFactory packetFactory;
ohair@286 95
alanb@368 96 public TieHandler(JavaMethodImpl method, WSBinding binding, MessageContextFactory mcf) {
ohair@286 97 this.soapVersion = binding.getSOAPVersion();
ohair@286 98 this.method = method.getMethod();
ohair@286 99 this.javaMethodModel = method;
ohair@286 100 argumentsBuilder = createArgumentsBuilder();
ohair@286 101 List<MessageFiller> fillers = new ArrayList<MessageFiller>();
ohair@286 102 bodyBuilder = createResponseMessageBuilder(fillers);
ohair@286 103 this.outFillers = fillers.toArray(new MessageFiller[fillers.size()]);
ohair@286 104 this.isOneWay = method.getMEP().isOneWay();
ohair@286 105 this.noOfArgs = this.method.getParameterTypes().length;
alanb@368 106 packetFactory = mcf;
ohair@286 107 }
ohair@286 108
ohair@286 109 /**
ohair@286 110 * It builds EndpointArgumentsBuilder which converts request {@link Message} to endpoint method's invocation
ohair@286 111 * arguments Object[]
ohair@286 112 *
ohair@286 113 * @return EndpointArgumentsBuilder
ohair@286 114 */
ohair@286 115 private EndpointArgumentsBuilder createArgumentsBuilder() {
ohair@286 116 EndpointArgumentsBuilder argsBuilder;
ohair@286 117 List<ParameterImpl> rp = javaMethodModel.getRequestParameters();
ohair@286 118 List<EndpointArgumentsBuilder> builders = new ArrayList<EndpointArgumentsBuilder>();
ohair@286 119
ohair@286 120 for( ParameterImpl param : rp ) {
ohair@286 121 EndpointValueSetter setter = EndpointValueSetter.get(param);
ohair@286 122 switch(param.getInBinding().kind) {
ohair@286 123 case BODY:
ohair@286 124 if(param.isWrapperStyle()) {
ohair@286 125 if(param.getParent().getBinding().isRpcLit())
ohair@286 126 builders.add(new EndpointArgumentsBuilder.RpcLit((WrapperParameter)param));
ohair@286 127 else
ohair@286 128 builders.add(new EndpointArgumentsBuilder.DocLit((WrapperParameter)param, Mode.OUT));
ohair@286 129 } else {
ohair@286 130 builders.add(new EndpointArgumentsBuilder.Body(param.getXMLBridge(),setter));
ohair@286 131 }
ohair@286 132 break;
ohair@286 133 case HEADER:
ohair@286 134 builders.add(new EndpointArgumentsBuilder.Header(soapVersion, param, setter));
ohair@286 135 break;
ohair@286 136 case ATTACHMENT:
ohair@286 137 builders.add(EndpointArgumentsBuilder.AttachmentBuilder.createAttachmentBuilder(param, setter));
ohair@286 138 break;
ohair@286 139 case UNBOUND:
ohair@286 140 builders.add(new EndpointArgumentsBuilder.NullSetter(setter,
ohair@286 141 EndpointArgumentsBuilder.getVMUninitializedValue(param.getTypeInfo().type)));
ohair@286 142 break;
ohair@286 143 default:
ohair@286 144 throw new AssertionError();
ohair@286 145 }
ohair@286 146 }
ohair@286 147
ohair@286 148 // creates {@link Holder} arguments for OUT parameters
ohair@286 149 List<ParameterImpl> resp = javaMethodModel.getResponseParameters();
ohair@286 150 for( ParameterImpl param : resp ) {
ohair@286 151 if (param.isWrapperStyle()) {
ohair@286 152 WrapperParameter wp = (WrapperParameter)param;
ohair@286 153 List<ParameterImpl> children = wp.getWrapperChildren();
ohair@286 154 for (ParameterImpl p : children) {
ohair@286 155 if (p.isOUT() && p.getIndex() != -1) {
ohair@286 156 EndpointValueSetter setter = EndpointValueSetter.get(p);
ohair@286 157 builders.add(new EndpointArgumentsBuilder.NullSetter(setter, null));
ohair@286 158 }
ohair@286 159 }
ohair@286 160 } else if (param.isOUT() && param.getIndex() != -1) {
ohair@286 161 EndpointValueSetter setter = EndpointValueSetter.get(param);
ohair@286 162 builders.add(new EndpointArgumentsBuilder.NullSetter(setter, null));
ohair@286 163 }
ohair@286 164 }
ohair@286 165
ohair@286 166 switch(builders.size()) {
ohair@286 167 case 0:
ohair@286 168 argsBuilder = EndpointArgumentsBuilder.NONE;
ohair@286 169 break;
ohair@286 170 case 1:
ohair@286 171 argsBuilder = builders.get(0);
ohair@286 172 break;
ohair@286 173 default:
ohair@286 174 argsBuilder = new EndpointArgumentsBuilder.Composite(builders);
ohair@286 175 }
ohair@286 176 return argsBuilder;
ohair@286 177 }
ohair@286 178
ohair@286 179 /**
ohair@286 180 * prepare objects for creating response {@link Message}
ohair@286 181 */
ohair@286 182 private EndpointResponseMessageBuilder createResponseMessageBuilder(List<MessageFiller> fillers) {
ohair@286 183
alanb@368 184 EndpointResponseMessageBuilder tmpBodyBuilder = null;
ohair@286 185 List<ParameterImpl> rp = javaMethodModel.getResponseParameters();
ohair@286 186
ohair@286 187 for (ParameterImpl param : rp) {
ohair@286 188 ValueGetter getter = ValueGetter.get(param);
ohair@286 189
ohair@286 190 switch(param.getOutBinding().kind) {
ohair@286 191 case BODY:
ohair@286 192 if(param.isWrapperStyle()) {
ohair@286 193 if(param.getParent().getBinding().isRpcLit()) {
alanb@368 194 tmpBodyBuilder = new EndpointResponseMessageBuilder.RpcLit((WrapperParameter)param,
ohair@286 195 soapVersion);
ohair@286 196 } else {
alanb@368 197 tmpBodyBuilder = new EndpointResponseMessageBuilder.DocLit((WrapperParameter)param,
ohair@286 198 soapVersion);
ohair@286 199 }
ohair@286 200 } else {
alanb@368 201 tmpBodyBuilder = new EndpointResponseMessageBuilder.Bare(param, soapVersion);
ohair@286 202 }
ohair@286 203 break;
ohair@286 204 case HEADER:
ohair@286 205 fillers.add(new MessageFiller.Header(param.getIndex(), param.getXMLBridge(), getter ));
ohair@286 206 break;
ohair@286 207 case ATTACHMENT:
ohair@286 208 fillers.add(MessageFiller.AttachmentFiller.createAttachmentFiller(param, getter));
ohair@286 209 break;
ohair@286 210 case UNBOUND:
ohair@286 211 break;
ohair@286 212 default:
ohair@286 213 throw new AssertionError(); // impossible
ohair@286 214 }
ohair@286 215 }
ohair@286 216
alanb@368 217 if (tmpBodyBuilder == null) {
ohair@286 218 // no parameter binds to body. we create an empty message
ohair@286 219 switch(soapVersion) {
ohair@286 220 case SOAP_11:
alanb@368 221 tmpBodyBuilder = EndpointResponseMessageBuilder.EMPTY_SOAP11;
ohair@286 222 break;
ohair@286 223 case SOAP_12:
alanb@368 224 tmpBodyBuilder = EndpointResponseMessageBuilder.EMPTY_SOAP12;
ohair@286 225 break;
ohair@286 226 default:
ohair@286 227 throw new AssertionError();
ohair@286 228 }
ohair@286 229 }
alanb@368 230 return tmpBodyBuilder;
ohair@286 231 }
ohair@286 232
ohair@286 233 public Object[] readRequest(Message reqMsg) {
ohair@286 234 Object[] args = new Object[noOfArgs];
ohair@286 235 try {
ohair@286 236 argumentsBuilder.readRequest(reqMsg,args);
ohair@286 237 } catch (JAXBException e) {
ohair@286 238 throw new WebServiceException(e);
ohair@286 239 } catch (XMLStreamException e) {
ohair@286 240 throw new WebServiceException(e);
ohair@286 241 }
ohair@286 242 return args;
ohair@286 243 }
ohair@286 244
ohair@286 245 public Message createResponse(JavaCallInfo call) {
ohair@286 246 Message responseMessage;
ohair@286 247 if (call.getException() == null) {
ohair@286 248 responseMessage = isOneWay ? null : createResponseMessage(call.getParameters(), call.getReturnValue());
ohair@286 249 } else {
ohair@286 250 Throwable e = call.getException();
ohair@286 251 Throwable serviceException = getServiceException(e);
ohair@286 252 if (e instanceof InvocationTargetException || serviceException != null) {
ohair@286 253 // Throwable cause = e.getCause();
ohair@286 254 //if (!(cause instanceof RuntimeException) && cause instanceof Exception) {
ohair@286 255 if (serviceException != null) {
ohair@286 256 // Service specific exception
ohair@286 257 LOGGER.log(Level.FINE, serviceException.getMessage(), serviceException);
ohair@286 258 responseMessage = SOAPFaultBuilder.createSOAPFaultMessage(soapVersion,
ohair@286 259 javaMethodModel.getCheckedException(serviceException.getClass()), serviceException);
ohair@286 260 } else {
ohair@286 261 Throwable cause = e.getCause();
ohair@286 262 if (cause instanceof ProtocolException) {
ohair@286 263 // Application code may be throwing it intentionally
ohair@286 264 LOGGER.log(Level.FINE, cause.getMessage(), cause);
ohair@286 265 } else {
ohair@286 266 // Probably some bug in application code
ohair@286 267 LOGGER.log(Level.SEVERE, cause.getMessage(), cause);
ohair@286 268 }
ohair@286 269 responseMessage = SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, cause);
ohair@286 270 }
ohair@286 271 } else if (e instanceof DispatchException) {
ohair@286 272 responseMessage = ((DispatchException)e).fault;
ohair@286 273 } else {
ohair@286 274 LOGGER.log(Level.SEVERE, e.getMessage(), e);
ohair@286 275 responseMessage = SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, e);
ohair@286 276 }
ohair@286 277 }
ohair@286 278 // return req.createServerResponse(responseMessage, req.endpoint.getPort(), javaMethodModel.getOwner(), req.endpoint.getBinding());
ohair@286 279
ohair@286 280 return responseMessage;
ohair@286 281 }
ohair@286 282
ohair@286 283 Throwable getServiceException(Throwable throwable) {
ohair@286 284 if (javaMethodModel.getCheckedException(throwable.getClass()) != null) return throwable;
ohair@286 285 if (throwable.getCause() != null) {
ohair@286 286 Throwable cause = throwable.getCause();
ohair@286 287 // if (!(cause instanceof RuntimeException) && cause instanceof Exception) {
ohair@286 288 if (javaMethodModel.getCheckedException(cause.getClass()) != null) return cause;
ohair@286 289 // }
ohair@286 290 // if (javaMethodModel.getCheckedException(cause.getClass()) != null) return cause;
ohair@286 291 }
ohair@286 292 return null;
ohair@286 293 }
ohair@286 294
ohair@286 295 /**
ohair@286 296 * Creates a response {@link JAXBMessage} from method arguments, return value
ohair@286 297 *
ohair@286 298 * @return response message
ohair@286 299 */
ohair@286 300 private Message createResponseMessage(Object[] args, Object returnValue) {
ohair@286 301 Message msg = bodyBuilder.createMessage(args, returnValue);
ohair@286 302
ohair@286 303 for (MessageFiller filler : outFillers)
ohair@286 304 filler.fillIn(args, returnValue, msg);
ohair@286 305
ohair@286 306 return msg;
ohair@286 307 }
ohair@286 308
ohair@286 309 public Method getMethod() {
ohair@286 310 return method;
ohair@286 311 }
ohair@286 312
ohair@286 313 private static final Logger LOGGER = Logger.getLogger(TieHandler.class.getName());
ohair@286 314
alanb@368 315 @Override
ohair@286 316 public JavaCallInfo deserializeRequest(Packet req) {
alanb@368 317 com.sun.xml.internal.ws.api.databinding.JavaCallInfo call = new com.sun.xml.internal.ws.api.databinding.JavaCallInfo();
ohair@286 318 call.setMethod(this.getMethod());
ohair@286 319 Object[] args = this.readRequest(req.getMessage());
ohair@286 320 call.setParameters(args);
ohair@286 321 return call;
ohair@286 322 }
ohair@286 323
alanb@368 324 @Override
ohair@286 325 public Packet serializeResponse(JavaCallInfo call) {
alanb@368 326 Message msg = this.createResponse(call);
alanb@368 327 Packet p = (msg == null) ? (Packet)packetFactory.createContext() : (Packet)packetFactory.createContext(msg);
alanb@368 328 p.setState(Packet.State.ServerResponse);
alanb@368 329 return p;
ohair@286 330 }
ohair@286 331
alanb@368 332 @Override
ohair@286 333 public JavaMethod getOperationModel() {
ohair@286 334 return javaMethodModel;
ohair@286 335 }
ohair@286 336 }

mercurial