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

Tue, 09 Apr 2013 14:51:13 +0100

author
alanb
date
Tue, 09 Apr 2013 14:51:13 +0100
changeset 368
0989ad8c0860
parent 286
f50545b5e2f1
child 637
9c07ef4934dd
permissions
-rw-r--r--

8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com

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
ohair@286 28 import com.sun.xml.internal.ws.api.SOAPVersion;
ohair@286 29 import com.sun.xml.internal.ws.api.message.Message;
ohair@286 30 import com.sun.xml.internal.ws.api.message.Messages;
ohair@286 31 import com.sun.xml.internal.ws.message.jaxb.JAXBMessage;
ohair@286 32 import com.sun.xml.internal.ws.model.ParameterImpl;
ohair@286 33 import com.sun.xml.internal.ws.model.WrapperParameter;
ohair@286 34 import com.sun.xml.internal.ws.spi.db.BindingContext;
ohair@286 35 import com.sun.xml.internal.ws.spi.db.XMLBridge;
ohair@286 36 import com.sun.xml.internal.ws.spi.db.PropertyAccessor;
ohair@286 37 import com.sun.xml.internal.ws.spi.db.WrapperComposite;
ohair@286 38
ohair@286 39 import javax.xml.bind.JAXBException;
ohair@286 40 import javax.xml.namespace.QName;
ohair@286 41 import javax.xml.ws.Holder;
ohair@286 42 import javax.xml.ws.WebServiceException;
ohair@286 43 import java.util.List;
ohair@286 44
ohair@286 45 /**
ohair@286 46 * Builds a JAXB object that represents the payload.
ohair@286 47 *
ohair@286 48 * @see MessageFiller
ohair@286 49 * @author Jitendra Kotamraju
ohair@286 50 */
ohair@286 51 public abstract class EndpointResponseMessageBuilder {
ohair@286 52 public abstract Message createMessage(Object[] methodArgs, Object returnValue);
ohair@286 53
ohair@286 54 public static final EndpointResponseMessageBuilder EMPTY_SOAP11 = new Empty(SOAPVersion.SOAP_11);
ohair@286 55 public static final EndpointResponseMessageBuilder EMPTY_SOAP12 = new Empty(SOAPVersion.SOAP_12);
ohair@286 56
ohair@286 57 private static final class Empty extends EndpointResponseMessageBuilder {
ohair@286 58 private final SOAPVersion soapVersion;
ohair@286 59
ohair@286 60 public Empty(SOAPVersion soapVersion) {
ohair@286 61 this.soapVersion = soapVersion;
ohair@286 62 }
ohair@286 63
ohair@286 64 public Message createMessage(Object[] methodArgs, Object returnValue) {
ohair@286 65 return Messages.createEmpty(soapVersion);
ohair@286 66 }
ohair@286 67 }
ohair@286 68
ohair@286 69 /**
ohair@286 70 * Base class for those {@link EndpointResponseMessageBuilder}s that build a {@link Message}
ohair@286 71 * from JAXB objects.
ohair@286 72 */
ohair@286 73 private static abstract class JAXB extends EndpointResponseMessageBuilder {
ohair@286 74 /**
ohair@286 75 * This object determines the binding of the object returned
ohair@286 76 * from {@link #createMessage(Object[], Object)}
ohair@286 77 */
ohair@286 78 private final XMLBridge bridge;
ohair@286 79 private final SOAPVersion soapVersion;
ohair@286 80
ohair@286 81 protected JAXB(XMLBridge bridge, SOAPVersion soapVersion) {
ohair@286 82 assert bridge!=null;
ohair@286 83 this.bridge = bridge;
ohair@286 84 this.soapVersion = soapVersion;
ohair@286 85 }
ohair@286 86
ohair@286 87 public final Message createMessage(Object[] methodArgs, Object returnValue) {
ohair@286 88 return JAXBMessage.create( bridge, build(methodArgs, returnValue), soapVersion );
ohair@286 89 }
ohair@286 90
ohair@286 91 /**
ohair@286 92 * Builds a JAXB object that becomes the payload.
ohair@286 93 */
ohair@286 94 abstract Object build(Object[] methodArgs, Object returnValue);
ohair@286 95 }
ohair@286 96
ohair@286 97 /**
ohair@286 98 * Used to create a payload JAXB object just by taking
ohair@286 99 * one of the parameters.
ohair@286 100 */
ohair@286 101 public final static class Bare extends JAXB {
ohair@286 102 /**
ohair@286 103 * The index of the method invocation parameters that goes into the payload.
ohair@286 104 */
ohair@286 105 private final int methodPos;
ohair@286 106
ohair@286 107 private final ValueGetter getter;
ohair@286 108
ohair@286 109 /**
ohair@286 110 * Creates a {@link EndpointResponseMessageBuilder} from a bare parameter.
ohair@286 111 */
ohair@286 112 public Bare(ParameterImpl p, SOAPVersion soapVersion) {
ohair@286 113 super(p.getXMLBridge(), soapVersion);
ohair@286 114 this.methodPos = p.getIndex();
ohair@286 115 this.getter = ValueGetter.get(p);
ohair@286 116 }
ohair@286 117
ohair@286 118 /**
ohair@286 119 * Picks up an object from the method arguments and uses it.
ohair@286 120 */
ohair@286 121 Object build(Object[] methodArgs, Object returnValue) {
ohair@286 122 if (methodPos == -1) {
ohair@286 123 return returnValue;
ohair@286 124 }
ohair@286 125 return getter.get(methodArgs[methodPos]);
ohair@286 126 }
ohair@286 127 }
ohair@286 128
ohair@286 129
ohair@286 130 /**
ohair@286 131 * Used to handle a 'wrapper' style request.
ohair@286 132 * Common part of rpc/lit and doc/lit.
ohair@286 133 */
ohair@286 134 abstract static class Wrapped extends JAXB {
ohair@286 135
ohair@286 136 /**
ohair@286 137 * Where in the method argument list do they come from?
ohair@286 138 */
ohair@286 139 protected final int[] indices;
ohair@286 140
ohair@286 141 /**
ohair@286 142 * Abstracts away the {@link Holder} handling when touching method arguments.
ohair@286 143 */
ohair@286 144 protected final ValueGetter[] getters;
ohair@286 145
alanb@368 146 /**
alanb@368 147 * How does each wrapped parameter binds to XML?
alanb@368 148 */
alanb@368 149 protected XMLBridge[] parameterBridges;
alanb@368 150
alanb@368 151 /**
alanb@368 152 * Used for error diagnostics.
alanb@368 153 */
alanb@368 154 protected List<ParameterImpl> children;
alanb@368 155
ohair@286 156 protected Wrapped(WrapperParameter wp, SOAPVersion soapVersion) {
ohair@286 157 super(wp.getXMLBridge(), soapVersion);
ohair@286 158
alanb@368 159 children = wp.getWrapperChildren();
ohair@286 160
ohair@286 161 indices = new int[children.size()];
ohair@286 162 getters = new ValueGetter[children.size()];
ohair@286 163 for( int i=0; i<indices.length; i++ ) {
ohair@286 164 ParameterImpl p = children.get(i);
ohair@286 165 indices[i] = p.getIndex();
ohair@286 166 getters[i] = ValueGetter.get(p);
ohair@286 167 }
ohair@286 168 }
alanb@368 169
alanb@368 170 /**
alanb@368 171 * Packs a bunch of arguments intoa {@link WrapperComposite}.
alanb@368 172 */
alanb@368 173 WrapperComposite buildWrapperComposite(Object[] methodArgs, Object returnValue) {
alanb@368 174 WrapperComposite cs = new WrapperComposite();
alanb@368 175 cs.bridges = parameterBridges;
alanb@368 176 cs.values = new Object[parameterBridges.length];
alanb@368 177
alanb@368 178 // fill in wrapped parameters from methodArgs
alanb@368 179 for( int i=indices.length-1; i>=0; i-- ) {
alanb@368 180 Object v;
alanb@368 181 if (indices[i] == -1) {
alanb@368 182 v = getters[i].get(returnValue);
alanb@368 183 } else {
alanb@368 184 v = getters[i].get(methodArgs[indices[i]]);
alanb@368 185 }
alanb@368 186 if(v==null) {
alanb@368 187 throw new WebServiceException("Method Parameter: "+
alanb@368 188 children.get(i).getName() +" cannot be null. This is BP 1.1 R2211 violation.");
alanb@368 189 }
alanb@368 190 cs.values[i] = v;
alanb@368 191 }
alanb@368 192
alanb@368 193 return cs;
alanb@368 194 }
ohair@286 195 }
ohair@286 196
ohair@286 197 /**
ohair@286 198 * Used to create a payload JAXB object by wrapping
ohair@286 199 * multiple parameters into one "wrapper bean".
ohair@286 200 */
ohair@286 201 public final static class DocLit extends Wrapped {
ohair@286 202 /**
ohair@286 203 * How does each wrapped parameter binds to XML?
ohair@286 204 */
ohair@286 205 private final PropertyAccessor[] accessors;
ohair@286 206
ohair@286 207 //private final RawAccessor retAccessor;
ohair@286 208
ohair@286 209 /**
ohair@286 210 * Wrapper bean.
ohair@286 211 */
ohair@286 212 private final Class wrapper;
alanb@368 213 private boolean dynamicWrapper;
ohair@286 214
ohair@286 215 /**
ohair@286 216 * Needed to get wrapper instantiation method.
ohair@286 217 */
ohair@286 218 private BindingContext bindingContext;
ohair@286 219
ohair@286 220 /**
ohair@286 221 * Creates a {@link EndpointResponseMessageBuilder} from a {@link WrapperParameter}.
ohair@286 222 */
ohair@286 223 public DocLit(WrapperParameter wp, SOAPVersion soapVersion) {
ohair@286 224 super(wp, soapVersion);
ohair@286 225 bindingContext = wp.getOwner().getBindingContext();
ohair@286 226 wrapper = (Class)wp.getXMLBridge().getTypeInfo().type;
alanb@368 227 dynamicWrapper = WrapperComposite.class.equals(wrapper);
alanb@368 228 children = wp.getWrapperChildren();
alanb@368 229 parameterBridges = new XMLBridge[children.size()];
ohair@286 230 accessors = new PropertyAccessor[children.size()];
ohair@286 231 for( int i=0; i<accessors.length; i++ ) {
ohair@286 232 ParameterImpl p = children.get(i);
ohair@286 233 QName name = p.getName();
alanb@368 234 if (dynamicWrapper) {
alanb@368 235 parameterBridges[i] = children.get(i).getInlinedRepeatedElementBridge();
alanb@368 236 if (parameterBridges[i] == null) parameterBridges[i] = children.get(i).getXMLBridge();
alanb@368 237 } else {
alanb@368 238 try {
alanb@368 239 accessors[i] = (dynamicWrapper) ? null :
alanb@368 240 p.getOwner().getBindingContext().getElementPropertyAccessor(
alanb@368 241 wrapper, name.getNamespaceURI(), name.getLocalPart() );
alanb@368 242 } catch (JAXBException e) {
alanb@368 243 throw new WebServiceException( // TODO: i18n
alanb@368 244 wrapper+" do not have a property of the name "+name,e);
alanb@368 245 }
ohair@286 246 }
ohair@286 247 }
ohair@286 248
ohair@286 249 }
ohair@286 250
ohair@286 251 /**
ohair@286 252 * Packs a bunch of arguments into a {@link WrapperComposite}.
ohair@286 253 */
ohair@286 254 Object build(Object[] methodArgs, Object returnValue) {
alanb@368 255 if (dynamicWrapper) return buildWrapperComposite(methodArgs, returnValue);
ohair@286 256 try {
ohair@286 257 //Object bean = wrapper.newInstance();
ohair@286 258 Object bean = bindingContext.newWrapperInstace(wrapper);
ohair@286 259
ohair@286 260 // fill in wrapped parameters from methodArgs
ohair@286 261 for( int i=indices.length-1; i>=0; i-- ) {
ohair@286 262 if (indices[i] == -1) {
ohair@286 263 accessors[i].set(bean, returnValue);
ohair@286 264 } else {
ohair@286 265 accessors[i].set(bean,getters[i].get(methodArgs[indices[i]]));
ohair@286 266 }
ohair@286 267 }
ohair@286 268
ohair@286 269 return bean;
ohair@286 270 } catch (InstantiationException e) {
ohair@286 271 // this is irrecoverable
ohair@286 272 Error x = new InstantiationError(e.getMessage());
ohair@286 273 x.initCause(e);
ohair@286 274 throw x;
ohair@286 275 } catch (IllegalAccessException e) {
ohair@286 276 // this is irrecoverable
ohair@286 277 Error x = new IllegalAccessError(e.getMessage());
ohair@286 278 x.initCause(e);
ohair@286 279 throw x;
ohair@286 280 } catch (com.sun.xml.internal.ws.spi.db.DatabindingException e) {
ohair@286 281 // this can happen when the set method throw a checked exception or something like that
ohair@286 282 throw new WebServiceException(e); // TODO:i18n
ohair@286 283 }
ohair@286 284 }
ohair@286 285 }
ohair@286 286
ohair@286 287
ohair@286 288 /**
ohair@286 289 * Used to create a payload JAXB object by wrapping
ohair@286 290 * multiple parameters into a {@link WrapperComposite}.
ohair@286 291 *
ohair@286 292 * <p>
ohair@286 293 * This is used for rpc/lit, as we don't have a wrapper bean for it.
ohair@286 294 * (TODO: Why don't we have a wrapper bean for this, when doc/lit does!?)
ohair@286 295 */
ohair@286 296 public final static class RpcLit extends Wrapped {
ohair@286 297
ohair@286 298 /**
ohair@286 299 * Creates a {@link EndpointResponseMessageBuilder} from a {@link WrapperParameter}.
ohair@286 300 */
ohair@286 301 public RpcLit(WrapperParameter wp, SOAPVersion soapVersion) {
ohair@286 302 super(wp, soapVersion);
ohair@286 303 // we'll use CompositeStructure to pack requests
ohair@286 304 assert wp.getTypeInfo().type==WrapperComposite.class;
ohair@286 305
ohair@286 306 parameterBridges = new XMLBridge[children.size()];
ohair@286 307 for( int i=0; i<parameterBridges.length; i++ )
ohair@286 308 parameterBridges[i] = children.get(i).getXMLBridge();
ohair@286 309 }
ohair@286 310
ohair@286 311 /**
ohair@286 312 * Packs a bunch of arguments intoa {@link WrapperComposite}.
ohair@286 313 */
alanb@368 314 Object build(Object[] methodArgs, Object returnValue) {
alanb@368 315 return buildWrapperComposite(methodArgs, returnValue);
ohair@286 316 }
ohair@286 317 }
ohair@286 318 }

mercurial