Thu, 31 Aug 2017 15:18:52 +0800
merge
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.api.model.wsdl.editable.EditableWSDLBoundFault;
33 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLBoundOperation;
34 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLBoundPortType;
35 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLMessage;
36 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLModel;
37 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLOperation;
38 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLPart;
39 import com.sun.xml.internal.ws.model.RuntimeModeler;
41 import javax.jws.WebParam.Mode;
42 import javax.jws.soap.SOAPBinding.Style;
43 import javax.xml.namespace.QName;
44 import javax.xml.stream.XMLStreamReader;
46 import java.util.*;
48 /**
49 * Implementation of {@link WSDLBoundOperation}
50 *
51 * @author Vivek Pandey
52 */
53 public final class WSDLBoundOperationImpl extends AbstractExtensibleImpl implements EditableWSDLBoundOperation {
54 private final QName name;
56 // map of wsdl:part to the binding
57 private final Map<String, ParameterBinding> inputParts;
58 private final Map<String, ParameterBinding> outputParts;
59 private final Map<String, ParameterBinding> faultParts;
60 private final Map<String, String> inputMimeTypes;
61 private final Map<String, String> outputMimeTypes;
62 private final Map<String, String> faultMimeTypes;
64 private boolean explicitInputSOAPBodyParts = false;
65 private boolean explicitOutputSOAPBodyParts = false;
66 private boolean explicitFaultSOAPBodyParts = false;
68 private Boolean emptyInputBody;
69 private Boolean emptyOutputBody;
70 private Boolean emptyFaultBody;
72 private final Map<String, EditableWSDLPart> inParts;
73 private final Map<String, EditableWSDLPart> outParts;
74 private final List<EditableWSDLBoundFault> wsdlBoundFaults;
75 private EditableWSDLOperation operation;
76 private String soapAction;
77 private ANONYMOUS anonymous;
79 private final EditableWSDLBoundPortType owner;
81 /**
82 *
83 * @param name wsdl:operation name qualified value
84 */
85 public WSDLBoundOperationImpl(XMLStreamReader xsr, EditableWSDLBoundPortType owner, QName name) {
86 super(xsr);
87 this.name = name;
88 inputParts = new HashMap<String, ParameterBinding>();
89 outputParts = new HashMap<String, ParameterBinding>();
90 faultParts = new HashMap<String, ParameterBinding>();
91 inputMimeTypes = new HashMap<String, String>();
92 outputMimeTypes = new HashMap<String, String>();
93 faultMimeTypes = new HashMap<String, String>();
94 inParts = new HashMap<String, EditableWSDLPart>();
95 outParts = new HashMap<String, EditableWSDLPart>();
96 wsdlBoundFaults = new ArrayList<EditableWSDLBoundFault>();
97 this.owner = owner;
98 }
100 @Override
101 public QName getName(){
102 return name;
103 }
105 @Override
106 public String getSOAPAction() {
107 return soapAction;
108 }
110 public void setSoapAction(String soapAction) {
111 this.soapAction = soapAction!=null?soapAction:"";
112 }
114 @Override
115 public EditableWSDLPart getPart(String partName, Mode mode) {
116 if(mode==Mode.IN){
117 return inParts.get(partName);
118 }else if(mode==Mode.OUT){
119 return outParts.get(partName);
120 }
121 return null;
122 }
124 public void addPart(EditableWSDLPart part, Mode mode){
125 if(mode==Mode.IN)
126 inParts.put(part.getName(), part);
127 else if(mode==Mode.OUT)
128 outParts.put(part.getName(), part);
129 }
131 /**
132 * Map of wsdl:input part name and the binding as {@link ParameterBinding}
133 *
134 * @return empty Map if there is no parts
135 */
136 public Map<String, ParameterBinding> getInputParts() {
137 return inputParts;
138 }
140 /**
141 * Map of wsdl:output part name and the binding as {@link ParameterBinding}
142 *
143 * @return empty Map if there is no parts
144 */
145 public Map<String, ParameterBinding> getOutputParts() {
146 return outputParts;
147 }
149 /**
150 * Map of wsdl:fault part name and the binding as {@link ParameterBinding}
151 *
152 * @return empty Map if there is no parts
153 */
154 public Map<String, ParameterBinding> getFaultParts() {
155 return faultParts;
156 }
158 // TODO: what's the difference between this and inputParts/outputParts?
159 @Override
160 public Map<String, ? extends EditableWSDLPart> getInParts() {
161 return Collections.<String, EditableWSDLPart>unmodifiableMap(inParts);
162 }
164 @Override
165 public Map<String, ? extends EditableWSDLPart> getOutParts() {
166 return Collections.<String, EditableWSDLPart>unmodifiableMap(outParts);
167 }
169 @NotNull
170 @Override
171 public List<? extends EditableWSDLBoundFault> getFaults() {
172 return wsdlBoundFaults;
173 }
175 public void addFault(@NotNull EditableWSDLBoundFault fault){
176 wsdlBoundFaults.add(fault);
177 }
180 /**
181 * Gets {@link ParameterBinding} for a given wsdl part in wsdl:input
182 *
183 * @param part Name of wsdl:part, must be non-null
184 * @return null if the part is not found.
185 */
186 public ParameterBinding getInputBinding(String part){
187 if(emptyInputBody == null){
188 if(inputParts.get(" ") != null)
189 emptyInputBody = true;
190 else
191 emptyInputBody = false;
192 }
193 ParameterBinding block = inputParts.get(part);
194 if(block == null){
195 if(explicitInputSOAPBodyParts || emptyInputBody)
196 return ParameterBinding.UNBOUND;
197 return ParameterBinding.BODY;
198 }
200 return block;
201 }
203 /**
204 * Gets {@link ParameterBinding} for a given wsdl part in wsdl:output
205 *
206 * @param part Name of wsdl:part, must be non-null
207 * @return null if the part is not found.
208 */
209 public ParameterBinding getOutputBinding(String part){
210 if(emptyOutputBody == null){
211 if(outputParts.get(" ") != null)
212 emptyOutputBody = true;
213 else
214 emptyOutputBody = false;
215 }
216 ParameterBinding block = outputParts.get(part);
217 if(block == null){
218 if(explicitOutputSOAPBodyParts || emptyOutputBody)
219 return ParameterBinding.UNBOUND;
220 return ParameterBinding.BODY;
221 }
223 return block;
224 }
226 /**
227 * Gets {@link ParameterBinding} for a given wsdl part in wsdl:fault
228 *
229 * @param part Name of wsdl:part, must be non-null
230 * @return null if the part is not found.
231 */
232 public ParameterBinding getFaultBinding(String part){
233 if(emptyFaultBody == null){
234 if(faultParts.get(" ") != null)
235 emptyFaultBody = true;
236 else
237 emptyFaultBody = false;
238 }
239 ParameterBinding block = faultParts.get(part);
240 if(block == null){
241 if(explicitFaultSOAPBodyParts || emptyFaultBody)
242 return ParameterBinding.UNBOUND;
243 return ParameterBinding.BODY;
244 }
246 return block;
247 }
249 /**
250 * Gets the MIME type for a given wsdl part in wsdl:input
251 *
252 * @param part Name of wsdl:part, must be non-null
253 * @return null if the part is not found.
254 */
255 public String getMimeTypeForInputPart(String part){
256 return inputMimeTypes.get(part);
257 }
259 /**
260 * Gets the MIME type for a given wsdl part in wsdl:output
261 *
262 * @param part Name of wsdl:part, must be non-null
263 * @return null if the part is not found.
264 */
265 public String getMimeTypeForOutputPart(String part){
266 return outputMimeTypes.get(part);
267 }
269 /**
270 * Gets the MIME type for a given wsdl part in wsdl:fault
271 *
272 * @param part Name of wsdl:part, must be non-null
273 * @return null if the part is not found.
274 */
275 public String getMimeTypeForFaultPart(String part){
276 return faultMimeTypes.get(part);
277 }
279 @Override
280 public EditableWSDLOperation getOperation() {
281 return operation;
282 }
285 @Override
286 public EditableWSDLBoundPortType getBoundPortType() {
287 return owner;
288 }
290 public void setInputExplicitBodyParts(boolean b) {
291 explicitInputSOAPBodyParts = b;
292 }
294 public void setOutputExplicitBodyParts(boolean b) {
295 explicitOutputSOAPBodyParts = b;
296 }
298 public void setFaultExplicitBodyParts(boolean b) {
299 explicitFaultSOAPBodyParts = b;
300 }
302 private Style style = Style.DOCUMENT;
303 public void setStyle(Style style){
304 this.style = style;
305 }
307 @Override
308 public @Nullable QName getRequestPayloadName() {
309 if (emptyRequestPayload)
310 return null;
312 if (requestPayloadName != null)
313 return requestPayloadName;
315 if(style.equals(Style.RPC)){
316 String ns = getRequestNamespace() != null ? getRequestNamespace() : name.getNamespaceURI();
317 requestPayloadName = new QName(ns, name.getLocalPart());
318 return requestPayloadName;
319 }else{
320 QName inMsgName = operation.getInput().getMessage().getName();
321 EditableWSDLMessage message = messages.get(inMsgName);
322 for(EditableWSDLPart part:message.parts()){
323 ParameterBinding binding = getInputBinding(part.getName());
324 if(binding.isBody()){
325 requestPayloadName = part.getDescriptor().name();
326 return requestPayloadName;
327 }
328 }
330 //Its empty payload
331 emptyRequestPayload = true;
332 }
333 //empty body
334 return null;
335 }
337 @Override
338 public @Nullable QName getResponsePayloadName() {
339 if (emptyResponsePayload)
340 return null;
342 if (responsePayloadName != null)
343 return responsePayloadName;
345 if(style.equals(Style.RPC)){
346 String ns = getResponseNamespace() != null ? getResponseNamespace() : name.getNamespaceURI();
347 responsePayloadName = new QName(ns, name.getLocalPart()+"Response");
348 return responsePayloadName;
349 }else{
350 QName outMsgName = operation.getOutput().getMessage().getName();
351 EditableWSDLMessage message = messages.get(outMsgName);
352 for(EditableWSDLPart part:message.parts()){
353 ParameterBinding binding = getOutputBinding(part.getName());
354 if(binding.isBody()){
355 responsePayloadName = part.getDescriptor().name();
356 return responsePayloadName;
357 }
358 }
360 //Its empty payload
361 emptyResponsePayload = true;
362 }
363 //empty body
364 return null;
365 }
368 private String reqNamespace;
369 private String respNamespace;
371 /**
372 * For rpclit gives namespace value on soapbinding:body@namespace
373 *
374 * @return non-null for rpclit and null for doclit
375 * @see RuntimeModeler#processRpcMethod(JavaMethodImpl, String, String, Method)
376 */
377 @Override
378 public String getRequestNamespace(){
379 return (reqNamespace != null)?reqNamespace:name.getNamespaceURI();
380 }
382 public void setRequestNamespace(String ns){
383 reqNamespace = ns;
384 }
386 /**
387 * For rpclit gives namespace value on soapbinding:body@namespace
388 *
389 * @return non-null for rpclit and null for doclit
390 * @see RuntimeModeler#processRpcMethod(JavaMethodImpl, String, String, Method)
391 */
392 @Override
393 public String getResponseNamespace(){
394 return (respNamespace!=null)?respNamespace:name.getNamespaceURI();
395 }
397 public void setResponseNamespace(String ns){
398 respNamespace = ns;
399 }
401 EditableWSDLBoundPortType getOwner(){
402 return owner;
403 }
405 private QName requestPayloadName;
406 private QName responsePayloadName;
407 private boolean emptyRequestPayload;
408 private boolean emptyResponsePayload;
409 private Map<QName, ? extends EditableWSDLMessage> messages;
411 public void freeze(EditableWSDLModel parent) {
412 messages = parent.getMessages();
413 operation = owner.getPortType().get(name.getLocalPart());
414 for(EditableWSDLBoundFault bf : wsdlBoundFaults){
415 bf.freeze(this);
416 }
417 }
419 public void setAnonymous(ANONYMOUS anonymous) {
420 this.anonymous = anonymous;
421 }
423 /**
424 * @inheritDoc
425 */
426 @Override
427 public ANONYMOUS getAnonymous() {
428 return anonymous;
429 }
430 }