Thu, 31 Aug 2017 15:18:52 +0800
merge
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.client.sei;
28 import com.oracle.webservices.internal.api.databinding.JavaCallInfo;
29 import com.sun.xml.internal.ws.api.SOAPVersion;
30 import com.sun.xml.internal.ws.api.databinding.ClientCallBridge;
31 import com.sun.xml.internal.ws.api.message.Message;
32 import com.sun.xml.internal.ws.api.message.MessageContextFactory;
33 import com.sun.xml.internal.ws.api.message.Packet;
34 import com.sun.xml.internal.ws.api.model.JavaMethod;
35 import com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
36 import com.sun.xml.internal.ws.model.CheckedExceptionImpl;
37 import com.sun.xml.internal.ws.model.JavaMethodImpl;
38 import com.sun.xml.internal.ws.model.ParameterImpl;
39 import com.sun.xml.internal.ws.model.WrapperParameter;
41 import javax.xml.namespace.QName;
43 import java.lang.reflect.Method;
44 import java.util.ArrayList;
45 import java.util.HashMap;
46 import java.util.List;
47 import java.util.Map;
49 /**
50 * {@link com.sun.xml.internal.ws.client.sei.MethodHandler} that handles synchronous method invocations.
51 * This is refactored from SEIMethodHandler.
52 * <p>
53 * This class mainly performs the following two tasks:
54 * <ol>
55 * <li>Accepts Object[] that represents arguments for a Java method,
56 * and creates {@link com.sun.xml.internal.ws.message.jaxb.JAXBMessage} that represents a request message.
57 * <li>Takes a {@link com.sun.xml.internal.ws.api.message.Message} that represents a response,
58 * and extracts the return value (and updates {@link javax.xml.ws.Holder }s.)
59 * </ol>
60 *
61 * <h2>Creating {@link com.sun.xml.internal.ws.message.jaxb.JAXBMessage }</h2>
62 * <p>
63 * At the construction time, we prepare {@link com.sun.xml.internal.ws.client.sei.BodyBuilder} and {@link com.sun.xml.internal.ws.client.sei.MessageFiller}s
64 * that know how to move arguments into a {@link com.sun.xml.internal.ws.api.message.Message }.
65 * Some arguments go to the payload, some go to headers, still others go to attachments.
66 *
67 * @author Kohsuke Kawaguchi
68 * @author Jitendra Kotamraju
69 * @author shih-chang.chen@oracle.com
70 */
71 public class StubHandler implements ClientCallBridge {
73 // these objects together create a message from method parameters
74 private final BodyBuilder bodyBuilder;
75 private final MessageFiller[] inFillers;
76 protected final String soapAction;
77 protected final boolean isOneWay;
78 protected final JavaMethodImpl javaMethod;
79 protected final Map<QName, CheckedExceptionImpl> checkedExceptions;
80 protected SOAPVersion soapVersion = SOAPVersion.SOAP_11;
81 protected ResponseBuilder responseBuilder;
82 protected MessageContextFactory packetFactory;
84 public StubHandler(JavaMethodImpl method, MessageContextFactory mcf) {
85 //keep all the CheckedException model for the detail qname
86 this.checkedExceptions = new HashMap<QName, CheckedExceptionImpl>();
87 for(CheckedExceptionImpl ce : method.getCheckedExceptions()){
88 checkedExceptions.put(ce.getBond().getTypeInfo().tagName, ce);
89 }
90 //If a non-"" soapAction is specified, wsa:action the SOAPAction
91 String soapActionFromBinding = method.getBinding().getSOAPAction();
92 if(method.getInputAction() != null && soapActionFromBinding != null && !soapActionFromBinding.equals("") ) {
93 this.soapAction = method.getInputAction();
94 } else {
95 this.soapAction = soapActionFromBinding;
96 }
97 this.javaMethod = method;
98 packetFactory = mcf;
100 soapVersion = javaMethod.getBinding().getSOAPVersion();
102 {// prepare objects for creating messages
103 List<ParameterImpl> rp = method.getRequestParameters();
105 BodyBuilder bodyBuilder = null;
106 List<MessageFiller> fillers = new ArrayList<MessageFiller>();
108 for (ParameterImpl param : rp) {
109 ValueGetter getter = getValueGetterFactory().get(param);
111 switch(param.getInBinding().kind) {
112 case BODY:
113 if(param.isWrapperStyle()) {
114 if(param.getParent().getBinding().isRpcLit())
115 bodyBuilder = new BodyBuilder.RpcLit((WrapperParameter)param, soapVersion, getValueGetterFactory());
116 else
117 bodyBuilder = new BodyBuilder.DocLit((WrapperParameter)param, soapVersion, getValueGetterFactory());
118 } else {
119 bodyBuilder = new BodyBuilder.Bare(param, soapVersion, getter);
120 }
121 break;
122 case HEADER:
123 fillers.add(new MessageFiller.Header(
124 param.getIndex(),
125 param.getXMLBridge(),
126 getter ));
127 break;
128 case ATTACHMENT:
129 fillers.add(MessageFiller.AttachmentFiller.createAttachmentFiller(param, getter));
130 break;
131 case UNBOUND:
132 break;
133 default:
134 throw new AssertionError(); // impossible
135 }
136 }
138 if(bodyBuilder==null) {
139 // no parameter binds to body. we create an empty message
140 switch(soapVersion) {
141 case SOAP_11:
142 bodyBuilder = BodyBuilder.EMPTY_SOAP11;
143 break;
144 case SOAP_12:
145 bodyBuilder = BodyBuilder.EMPTY_SOAP12;
146 break;
147 default:
148 throw new AssertionError();
149 }
150 }
152 this.bodyBuilder = bodyBuilder;
153 this.inFillers = fillers.toArray(new MessageFiller[fillers.size()]);
154 }
156 this.isOneWay = method.getMEP().isOneWay();
157 responseBuilder = buildResponseBuilder(method, ValueSetterFactory.SYNC);
158 }
160 ResponseBuilder buildResponseBuilder(JavaMethodImpl method, ValueSetterFactory setterFactory) {
161 // prepare objects for processing response
162 List<ParameterImpl> rp = method.getResponseParameters();
163 List<ResponseBuilder> builders = new ArrayList<ResponseBuilder>();
165 for( ParameterImpl param : rp ) {
166 ValueSetter setter;
167 switch(param.getOutBinding().kind) {
168 case BODY:
169 if(param.isWrapperStyle()) {
170 if(param.getParent().getBinding().isRpcLit())
171 builders.add(new ResponseBuilder.RpcLit((WrapperParameter)param, setterFactory));
172 else
173 builders.add(new ResponseBuilder.DocLit((WrapperParameter)param, setterFactory));
174 } else {
175 setter = setterFactory.get(param);
176 builders.add(new ResponseBuilder.Body(param.getXMLBridge(),setter));
177 }
178 break;
179 case HEADER:
180 setter = setterFactory.get(param);
181 builders.add(new ResponseBuilder.Header(soapVersion, param, setter));
182 break;
183 case ATTACHMENT:
184 setter = setterFactory.get(param);
185 builders.add(ResponseBuilder.AttachmentBuilder.createAttachmentBuilder(param, setter));
186 break;
187 case UNBOUND:
188 setter = setterFactory.get(param);
189 builders.add(new ResponseBuilder.NullSetter(setter,
190 ResponseBuilder.getVMUninitializedValue(param.getTypeInfo().type)));
191 break;
192 default:
193 throw new AssertionError();
194 }
195 }
196 ResponseBuilder rb;
197 switch(builders.size()) {
198 case 0:
199 rb = ResponseBuilder.NONE;
200 break;
201 case 1:
202 rb = builders.get(0);
203 break;
204 default:
205 rb = new ResponseBuilder.Composite(builders);
206 }
207 return rb;
208 }
211 /**
212 * Creates a request {@link com.sun.xml.internal.ws.message.jaxb.JAXBMessage} from method arguments.
213 * @param args proxy invocation arguments
214 * @return Message for the arguments
215 */
216 public Packet createRequestPacket(JavaCallInfo args) {
217 Message msg = bodyBuilder.createMessage(args.getParameters());
219 for (MessageFiller filler : inFillers) filler.fillIn(args.getParameters(),msg);
221 Packet req = (Packet)packetFactory.createContext(msg);
222 req.setState(Packet.State.ClientRequest);
223 req.soapAction = soapAction;
224 req.expectReply = !isOneWay;
225 req.getMessage().assertOneWay(isOneWay);
226 req.setWSDLOperation(getOperationName());
227 return req;
228 }
230 ValueGetterFactory getValueGetterFactory() {
231 return ValueGetterFactory.SYNC;
232 }
234 public JavaCallInfo readResponse(Packet p, JavaCallInfo call) throws Throwable {
235 Message msg = p.getMessage();
236 if(msg.isFault()) {
237 SOAPFaultBuilder faultBuilder = SOAPFaultBuilder.create(msg);
238 Throwable t = faultBuilder.createException(checkedExceptions);
239 call.setException(t);
240 throw t;
241 } else {
242 initArgs(call.getParameters());
243 Object ret = responseBuilder.readResponse(msg, call.getParameters());
244 call.setReturnValue(ret);
245 return call;
246 }
247 }
249 public QName getOperationName() {
250 //TODO javaMethod.getOperation()
251 return javaMethod.getOperationQName();
252 }
254 public String getSoapAction() {
255 return soapAction;
256 }
258 public boolean isOneWay() {
259 return isOneWay;
260 }
262 protected void initArgs(Object[] args) throws Exception {
263 }
265 public Method getMethod() {
266 return javaMethod.getMethod();
267 }
269 public JavaMethod getOperationModel() {
270 return javaMethod;
271 }
272 }