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

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

mercurial