Wed, 12 Jun 2013 14:47:09 +0100
8013021: Rebase 8005432 & 8003542 against the latest jdk8/jaxws
8003542: Improve processing of MTOM attachments
8005432: Update access to JAX-WS
Reviewed-by: mullan
1 /*
2 * Copyright (c) 1997, 2013, 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.model.wsdl;
28 import com.sun.istack.internal.Nullable;
29 import com.sun.istack.internal.NotNull;
30 import com.sun.xml.internal.ws.api.model.ParameterBinding;
31 import com.sun.xml.internal.ws.api.model.wsdl.*;
32 import com.sun.xml.internal.ws.model.RuntimeModeler;
34 import javax.jws.WebParam.Mode;
35 import javax.jws.soap.SOAPBinding.Style;
36 import javax.xml.namespace.QName;
37 import javax.xml.stream.XMLStreamReader;
38 import java.util.*;
40 /**
41 * Implementation of {@link WSDLBoundOperation}
42 *
43 * @author Vivek Pandey
44 */
45 public final class WSDLBoundOperationImpl extends AbstractExtensibleImpl implements WSDLBoundOperation {
46 private final QName name;
48 // map of wsdl:part to the binding
49 private final Map<String, ParameterBinding> inputParts;
50 private final Map<String, ParameterBinding> outputParts;
51 private final Map<String, ParameterBinding> faultParts;
52 private final Map<String, String> inputMimeTypes;
53 private final Map<String, String> outputMimeTypes;
54 private final Map<String, String> faultMimeTypes;
56 private boolean explicitInputSOAPBodyParts = false;
57 private boolean explicitOutputSOAPBodyParts = false;
58 private boolean explicitFaultSOAPBodyParts = false;
60 private Boolean emptyInputBody;
61 private Boolean emptyOutputBody;
62 private Boolean emptyFaultBody;
64 private final Map<String, WSDLPartImpl> inParts;
65 private final Map<String, WSDLPartImpl> outParts;
66 private final List<WSDLBoundFaultImpl> wsdlBoundFaults;
67 private WSDLOperationImpl operation;
68 private String soapAction;
69 private ANONYMOUS anonymous;
71 private final WSDLBoundPortTypeImpl owner;
73 /**
74 *
75 * @param name wsdl:operation name qualified value
76 */
77 public WSDLBoundOperationImpl(XMLStreamReader xsr, WSDLBoundPortTypeImpl owner, QName name) {
78 super(xsr);
79 this.name = name;
80 inputParts = new HashMap<String, ParameterBinding>();
81 outputParts = new HashMap<String, ParameterBinding>();
82 faultParts = new HashMap<String, ParameterBinding>();
83 inputMimeTypes = new HashMap<String, String>();
84 outputMimeTypes = new HashMap<String, String>();
85 faultMimeTypes = new HashMap<String, String>();
86 inParts = new HashMap<String, WSDLPartImpl>();
87 outParts = new HashMap<String, WSDLPartImpl>();
88 wsdlBoundFaults = new ArrayList<WSDLBoundFaultImpl>();
89 this.owner = owner;
90 }
92 @Override
93 public QName getName(){
94 return name;
95 }
97 @Override
98 public String getSOAPAction() {
99 return soapAction;
100 }
102 public void setSoapAction(String soapAction) {
103 this.soapAction = soapAction!=null?soapAction:"";
104 }
106 @Override
107 public WSDLPartImpl getPart(String partName, Mode mode) {
108 if(mode==Mode.IN){
109 return inParts.get(partName);
110 }else if(mode==Mode.OUT){
111 return outParts.get(partName);
112 }
113 return null;
114 }
116 public void addPart(WSDLPartImpl part, Mode mode){
117 if(mode==Mode.IN)
118 inParts.put(part.getName(), part);
119 else if(mode==Mode.OUT)
120 outParts.put(part.getName(), part);
121 }
123 /**
124 * Map of wsdl:input part name and the binding as {@link ParameterBinding}
125 *
126 * @return empty Map if there is no parts
127 */
128 public Map<String, ParameterBinding> getInputParts() {
129 return inputParts;
130 }
132 /**
133 * Map of wsdl:output part name and the binding as {@link ParameterBinding}
134 *
135 * @return empty Map if there is no parts
136 */
137 public Map<String, ParameterBinding> getOutputParts() {
138 return outputParts;
139 }
141 /**
142 * Map of wsdl:fault part name and the binding as {@link ParameterBinding}
143 *
144 * @return empty Map if there is no parts
145 */
146 public Map<String, ParameterBinding> getFaultParts() {
147 return faultParts;
148 }
150 // TODO: what's the difference between this and inputParts/outputParts?
151 @Override
152 public Map<String,WSDLPart> getInParts() {
153 return Collections.<String,WSDLPart>unmodifiableMap(inParts);
154 }
156 @Override
157 public Map<String,WSDLPart> getOutParts() {
158 return Collections.<String,WSDLPart>unmodifiableMap(outParts);
159 }
161 @NotNull
162 @Override
163 public List<WSDLBoundFaultImpl> getFaults() {
164 return wsdlBoundFaults;
165 }
167 public void addFault(@NotNull WSDLBoundFaultImpl fault){
168 wsdlBoundFaults.add(fault);
169 }
172 /**
173 * Map of mime:content@part and the mime type from mime:content@type for wsdl:output
174 *
175 * @return empty Map if there is no parts
176 */
177 public Map<String, String> getInputMimeTypes() {
178 return inputMimeTypes;
179 }
181 /**
182 * Map of mime:content@part and the mime type from mime:content@type for wsdl:output
183 *
184 * @return empty Map if there is no parts
185 */
186 public Map<String, String> getOutputMimeTypes() {
187 return outputMimeTypes;
188 }
190 /**
191 * Map of mime:content@part and the mime type from mime:content@type for wsdl:fault
192 *
193 * @return empty Map if there is no parts
194 */
195 public Map<String, String> getFaultMimeTypes() {
196 return faultMimeTypes;
197 }
199 /**
200 * Gets {@link ParameterBinding} for a given wsdl part in wsdl:input
201 *
202 * @param part Name of wsdl:part, must be non-null
203 * @return null if the part is not found.
204 */
205 public ParameterBinding getInputBinding(String part){
206 if(emptyInputBody == null){
207 if(inputParts.get(" ") != null)
208 emptyInputBody = true;
209 else
210 emptyInputBody = false;
211 }
212 ParameterBinding block = inputParts.get(part);
213 if(block == null){
214 if(explicitInputSOAPBodyParts || emptyInputBody)
215 return ParameterBinding.UNBOUND;
216 return ParameterBinding.BODY;
217 }
219 return block;
220 }
222 /**
223 * Gets {@link ParameterBinding} for a given wsdl part in wsdl:output
224 *
225 * @param part Name of wsdl:part, must be non-null
226 * @return null if the part is not found.
227 */
228 public ParameterBinding getOutputBinding(String part){
229 if(emptyOutputBody == null){
230 if(outputParts.get(" ") != null)
231 emptyOutputBody = true;
232 else
233 emptyOutputBody = false;
234 }
235 ParameterBinding block = outputParts.get(part);
236 if(block == null){
237 if(explicitOutputSOAPBodyParts || emptyOutputBody)
238 return ParameterBinding.UNBOUND;
239 return ParameterBinding.BODY;
240 }
242 return block;
243 }
245 /**
246 * Gets {@link ParameterBinding} for a given wsdl part in wsdl:fault
247 *
248 * @param part Name of wsdl:part, must be non-null
249 * @return null if the part is not found.
250 */
251 public ParameterBinding getFaultBinding(String part){
252 if(emptyFaultBody == null){
253 if(faultParts.get(" ") != null)
254 emptyFaultBody = true;
255 else
256 emptyFaultBody = false;
257 }
258 ParameterBinding block = faultParts.get(part);
259 if(block == null){
260 if(explicitFaultSOAPBodyParts || emptyFaultBody)
261 return ParameterBinding.UNBOUND;
262 return ParameterBinding.BODY;
263 }
265 return block;
266 }
268 /**
269 * Gets the MIME type for a given wsdl part in wsdl:input
270 *
271 * @param part Name of wsdl:part, must be non-null
272 * @return null if the part is not found.
273 */
274 public String getMimeTypeForInputPart(String part){
275 return inputMimeTypes.get(part);
276 }
278 /**
279 * Gets the MIME type for a given wsdl part in wsdl:output
280 *
281 * @param part Name of wsdl:part, must be non-null
282 * @return null if the part is not found.
283 */
284 public String getMimeTypeForOutputPart(String part){
285 return outputMimeTypes.get(part);
286 }
288 /**
289 * Gets the MIME type for a given wsdl part in wsdl:fault
290 *
291 * @param part Name of wsdl:part, must be non-null
292 * @return null if the part is not found.
293 */
294 public String getMimeTypeForFaultPart(String part){
295 return faultMimeTypes.get(part);
296 }
298 @Override
299 public WSDLOperationImpl getOperation() {
300 return operation;
301 }
304 @Override
305 public WSDLBoundPortType getBoundPortType() {
306 return owner;
307 }
309 public void setInputExplicitBodyParts(boolean b) {
310 explicitInputSOAPBodyParts = b;
311 }
313 public void setOutputExplicitBodyParts(boolean b) {
314 explicitOutputSOAPBodyParts = b;
315 }
317 public void setFaultExplicitBodyParts(boolean b) {
318 explicitFaultSOAPBodyParts = b;
319 }
321 private Style style = Style.DOCUMENT;
322 public void setStyle(Style style){
323 this.style = style;
324 }
326 @Override
327 public @Nullable QName getReqPayloadName() {
328 if (emptyRequestPayload)
329 return null;
331 if (requestPayloadName != null)
332 return requestPayloadName;
334 if(style.equals(Style.RPC)){
335 String ns = getRequestNamespace() != null ? getRequestNamespace() : name.getNamespaceURI();
336 requestPayloadName = new QName(ns, name.getLocalPart());
337 return requestPayloadName;
338 }else{
339 QName inMsgName = operation.getInput().getMessage().getName();
340 WSDLMessageImpl message = messages.get(inMsgName);
341 for(WSDLPartImpl part:message.parts()){
342 ParameterBinding binding = getInputBinding(part.getName());
343 if(binding.isBody()){
344 requestPayloadName = part.getDescriptor().name();
345 return requestPayloadName;
346 }
347 }
349 //Its empty payload
350 emptyRequestPayload = true;
351 }
352 //empty body
353 return null;
354 }
356 @Override
357 public @Nullable QName getResPayloadName() {
358 if (emptyResponsePayload)
359 return null;
361 if (responsePayloadName != null)
362 return responsePayloadName;
364 if(style.equals(Style.RPC)){
365 String ns = getResponseNamespace() != null ? getResponseNamespace() : name.getNamespaceURI();
366 responsePayloadName = new QName(ns, name.getLocalPart()+"Response");
367 return responsePayloadName;
368 }else{
369 QName outMsgName = operation.getOutput().getMessage().getName();
370 WSDLMessageImpl message = messages.get(outMsgName);
371 for(WSDLPartImpl part:message.parts()){
372 ParameterBinding binding = getOutputBinding(part.getName());
373 if(binding.isBody()){
374 responsePayloadName = part.getDescriptor().name();
375 return responsePayloadName;
376 }
377 }
379 //Its empty payload
380 emptyResponsePayload = true;
381 }
382 //empty body
383 return null;
384 }
387 private String reqNamespace;
388 private String respNamespace;
390 /**
391 * For rpclit gives namespace value on soapbinding:body@namespace
392 *
393 * @return non-null for rpclit and null for doclit
394 * @see RuntimeModeler#processRpcMethod(JavaMethodImpl, String, String, Method)
395 */
396 @Override
397 public String getRequestNamespace(){
398 return (reqNamespace != null)?reqNamespace:name.getNamespaceURI();
399 }
401 public void setRequestNamespace(String ns){
402 reqNamespace = ns;
403 }
406 /**
407 * For rpclit gives namespace value on soapbinding:body@namespace
408 *
409 * @return non-null for rpclit and null for doclit
410 * @see RuntimeModeler#processRpcMethod(JavaMethodImpl, String, String, Method)
411 */
412 @Override
413 public String getResponseNamespace(){
414 return (respNamespace!=null)?respNamespace:name.getNamespaceURI();
415 }
417 public void setResponseNamespace(String ns){
418 respNamespace = ns;
419 }
421 WSDLBoundPortTypeImpl getOwner(){
422 return owner;
423 }
425 private QName requestPayloadName;
426 private QName responsePayloadName;
427 private boolean emptyRequestPayload;
428 private boolean emptyResponsePayload;
429 private Map<QName, WSDLMessageImpl> messages;
431 void freeze(WSDLModelImpl parent) {
432 messages = parent.getMessages();
433 operation = owner.getPortType().get(name.getLocalPart());
434 for(WSDLBoundFaultImpl bf : wsdlBoundFaults){
435 bf.freeze(this);
436 }
437 }
439 public void setAnonymous(ANONYMOUS anonymous) {
440 this.anonymous = anonymous;
441 }
443 /**
444 * @inheritDoc
445 */
446 @Override
447 public ANONYMOUS getAnonymous() {
448 return anonymous;
449 }
450 }