ohair@286: /* mkos@384: * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. ohair@286: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ohair@286: * ohair@286: * This code is free software; you can redistribute it and/or modify it ohair@286: * under the terms of the GNU General Public License version 2 only, as ohair@286: * published by the Free Software Foundation. Oracle designates this ohair@286: * particular file as subject to the "Classpath" exception as provided ohair@286: * by Oracle in the LICENSE file that accompanied this code. ohair@286: * ohair@286: * This code is distributed in the hope that it will be useful, but WITHOUT ohair@286: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ohair@286: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ohair@286: * version 2 for more details (a copy is included in the LICENSE file that ohair@286: * accompanied this code). ohair@286: * ohair@286: * You should have received a copy of the GNU General Public License version ohair@286: * 2 along with this work; if not, write to the Free Software Foundation, ohair@286: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ohair@286: * ohair@286: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@286: * or visit www.oracle.com if you need additional information or have any ohair@286: * questions. ohair@286: */ ohair@286: ohair@286: package com.sun.xml.internal.ws.model.wsdl; ohair@286: ohair@286: import com.sun.istack.internal.Nullable; ohair@286: import com.sun.istack.internal.NotNull; ohair@286: import com.sun.xml.internal.ws.api.model.ParameterBinding; ohair@286: import com.sun.xml.internal.ws.api.model.wsdl.*; mkos@408: import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLBoundFault; mkos@408: import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLBoundOperation; mkos@408: import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLBoundPortType; mkos@408: import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLMessage; mkos@408: import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLModel; mkos@408: import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLOperation; mkos@408: import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLPart; alanb@368: import com.sun.xml.internal.ws.model.RuntimeModeler; ohair@286: ohair@286: import javax.jws.WebParam.Mode; ohair@286: import javax.jws.soap.SOAPBinding.Style; ohair@286: import javax.xml.namespace.QName; ohair@286: import javax.xml.stream.XMLStreamReader; mkos@408: ohair@286: import java.util.*; ohair@286: ohair@286: /** ohair@286: * Implementation of {@link WSDLBoundOperation} ohair@286: * ohair@286: * @author Vivek Pandey ohair@286: */ mkos@408: public final class WSDLBoundOperationImpl extends AbstractExtensibleImpl implements EditableWSDLBoundOperation { ohair@286: private final QName name; ohair@286: ohair@286: // map of wsdl:part to the binding ohair@286: private final Map inputParts; ohair@286: private final Map outputParts; ohair@286: private final Map faultParts; ohair@286: private final Map inputMimeTypes; ohair@286: private final Map outputMimeTypes; ohair@286: private final Map faultMimeTypes; ohair@286: ohair@286: private boolean explicitInputSOAPBodyParts = false; ohair@286: private boolean explicitOutputSOAPBodyParts = false; ohair@286: private boolean explicitFaultSOAPBodyParts = false; ohair@286: ohair@286: private Boolean emptyInputBody; ohair@286: private Boolean emptyOutputBody; ohair@286: private Boolean emptyFaultBody; ohair@286: mkos@408: private final Map inParts; mkos@408: private final Map outParts; mkos@408: private final List wsdlBoundFaults; mkos@408: private EditableWSDLOperation operation; ohair@286: private String soapAction; ohair@286: private ANONYMOUS anonymous; ohair@286: mkos@408: private final EditableWSDLBoundPortType owner; ohair@286: ohair@286: /** ohair@286: * ohair@286: * @param name wsdl:operation name qualified value ohair@286: */ mkos@408: public WSDLBoundOperationImpl(XMLStreamReader xsr, EditableWSDLBoundPortType owner, QName name) { ohair@286: super(xsr); ohair@286: this.name = name; ohair@286: inputParts = new HashMap(); ohair@286: outputParts = new HashMap(); ohair@286: faultParts = new HashMap(); ohair@286: inputMimeTypes = new HashMap(); ohair@286: outputMimeTypes = new HashMap(); ohair@286: faultMimeTypes = new HashMap(); mkos@408: inParts = new HashMap(); mkos@408: outParts = new HashMap(); mkos@408: wsdlBoundFaults = new ArrayList(); ohair@286: this.owner = owner; ohair@286: } ohair@286: mkos@384: @Override ohair@286: public QName getName(){ ohair@286: return name; ohair@286: } ohair@286: mkos@384: @Override ohair@286: public String getSOAPAction() { ohair@286: return soapAction; ohair@286: } ohair@286: ohair@286: public void setSoapAction(String soapAction) { ohair@286: this.soapAction = soapAction!=null?soapAction:""; ohair@286: } ohair@286: mkos@384: @Override mkos@408: public EditableWSDLPart getPart(String partName, Mode mode) { ohair@286: if(mode==Mode.IN){ ohair@286: return inParts.get(partName); ohair@286: }else if(mode==Mode.OUT){ ohair@286: return outParts.get(partName); ohair@286: } ohair@286: return null; ohair@286: } ohair@286: mkos@408: public void addPart(EditableWSDLPart part, Mode mode){ ohair@286: if(mode==Mode.IN) ohair@286: inParts.put(part.getName(), part); ohair@286: else if(mode==Mode.OUT) ohair@286: outParts.put(part.getName(), part); ohair@286: } ohair@286: ohair@286: /** ohair@286: * Map of wsdl:input part name and the binding as {@link ParameterBinding} ohair@286: * ohair@286: * @return empty Map if there is no parts ohair@286: */ ohair@286: public Map getInputParts() { ohair@286: return inputParts; ohair@286: } ohair@286: ohair@286: /** ohair@286: * Map of wsdl:output part name and the binding as {@link ParameterBinding} ohair@286: * ohair@286: * @return empty Map if there is no parts ohair@286: */ ohair@286: public Map getOutputParts() { ohair@286: return outputParts; ohair@286: } ohair@286: ohair@286: /** ohair@286: * Map of wsdl:fault part name and the binding as {@link ParameterBinding} ohair@286: * ohair@286: * @return empty Map if there is no parts ohair@286: */ ohair@286: public Map getFaultParts() { ohair@286: return faultParts; ohair@286: } ohair@286: ohair@286: // TODO: what's the difference between this and inputParts/outputParts? mkos@384: @Override mkos@408: public Map getInParts() { mkos@408: return Collections.unmodifiableMap(inParts); ohair@286: } ohair@286: mkos@384: @Override mkos@408: public Map getOutParts() { mkos@408: return Collections.unmodifiableMap(outParts); ohair@286: } ohair@286: ohair@286: @NotNull mkos@384: @Override mkos@408: public List getFaults() { ohair@286: return wsdlBoundFaults; ohair@286: } ohair@286: mkos@408: public void addFault(@NotNull EditableWSDLBoundFault fault){ ohair@286: wsdlBoundFaults.add(fault); ohair@286: } ohair@286: ohair@286: ohair@286: /** ohair@286: * Gets {@link ParameterBinding} for a given wsdl part in wsdl:input ohair@286: * ohair@286: * @param part Name of wsdl:part, must be non-null ohair@286: * @return null if the part is not found. ohair@286: */ ohair@286: public ParameterBinding getInputBinding(String part){ ohair@286: if(emptyInputBody == null){ ohair@286: if(inputParts.get(" ") != null) ohair@286: emptyInputBody = true; ohair@286: else ohair@286: emptyInputBody = false; ohair@286: } ohair@286: ParameterBinding block = inputParts.get(part); ohair@286: if(block == null){ ohair@286: if(explicitInputSOAPBodyParts || emptyInputBody) ohair@286: return ParameterBinding.UNBOUND; ohair@286: return ParameterBinding.BODY; ohair@286: } ohair@286: ohair@286: return block; ohair@286: } ohair@286: ohair@286: /** ohair@286: * Gets {@link ParameterBinding} for a given wsdl part in wsdl:output ohair@286: * ohair@286: * @param part Name of wsdl:part, must be non-null ohair@286: * @return null if the part is not found. ohair@286: */ ohair@286: public ParameterBinding getOutputBinding(String part){ ohair@286: if(emptyOutputBody == null){ ohair@286: if(outputParts.get(" ") != null) ohair@286: emptyOutputBody = true; ohair@286: else ohair@286: emptyOutputBody = false; ohair@286: } ohair@286: ParameterBinding block = outputParts.get(part); ohair@286: if(block == null){ ohair@286: if(explicitOutputSOAPBodyParts || emptyOutputBody) ohair@286: return ParameterBinding.UNBOUND; ohair@286: return ParameterBinding.BODY; ohair@286: } ohair@286: ohair@286: return block; ohair@286: } ohair@286: ohair@286: /** ohair@286: * Gets {@link ParameterBinding} for a given wsdl part in wsdl:fault ohair@286: * ohair@286: * @param part Name of wsdl:part, must be non-null ohair@286: * @return null if the part is not found. ohair@286: */ ohair@286: public ParameterBinding getFaultBinding(String part){ ohair@286: if(emptyFaultBody == null){ ohair@286: if(faultParts.get(" ") != null) ohair@286: emptyFaultBody = true; ohair@286: else ohair@286: emptyFaultBody = false; ohair@286: } ohair@286: ParameterBinding block = faultParts.get(part); ohair@286: if(block == null){ ohair@286: if(explicitFaultSOAPBodyParts || emptyFaultBody) ohair@286: return ParameterBinding.UNBOUND; ohair@286: return ParameterBinding.BODY; ohair@286: } ohair@286: ohair@286: return block; ohair@286: } ohair@286: ohair@286: /** ohair@286: * Gets the MIME type for a given wsdl part in wsdl:input ohair@286: * ohair@286: * @param part Name of wsdl:part, must be non-null ohair@286: * @return null if the part is not found. ohair@286: */ ohair@286: public String getMimeTypeForInputPart(String part){ ohair@286: return inputMimeTypes.get(part); ohair@286: } ohair@286: ohair@286: /** ohair@286: * Gets the MIME type for a given wsdl part in wsdl:output ohair@286: * ohair@286: * @param part Name of wsdl:part, must be non-null ohair@286: * @return null if the part is not found. ohair@286: */ ohair@286: public String getMimeTypeForOutputPart(String part){ ohair@286: return outputMimeTypes.get(part); ohair@286: } ohair@286: ohair@286: /** ohair@286: * Gets the MIME type for a given wsdl part in wsdl:fault ohair@286: * ohair@286: * @param part Name of wsdl:part, must be non-null ohair@286: * @return null if the part is not found. ohair@286: */ ohair@286: public String getMimeTypeForFaultPart(String part){ ohair@286: return faultMimeTypes.get(part); ohair@286: } ohair@286: mkos@384: @Override mkos@408: public EditableWSDLOperation getOperation() { ohair@286: return operation; ohair@286: } ohair@286: ohair@286: mkos@384: @Override mkos@408: public EditableWSDLBoundPortType getBoundPortType() { ohair@286: return owner; ohair@286: } ohair@286: ohair@286: public void setInputExplicitBodyParts(boolean b) { ohair@286: explicitInputSOAPBodyParts = b; ohair@286: } ohair@286: ohair@286: public void setOutputExplicitBodyParts(boolean b) { ohair@286: explicitOutputSOAPBodyParts = b; ohair@286: } ohair@286: ohair@286: public void setFaultExplicitBodyParts(boolean b) { ohair@286: explicitFaultSOAPBodyParts = b; ohair@286: } ohair@286: ohair@286: private Style style = Style.DOCUMENT; ohair@286: public void setStyle(Style style){ ohair@286: this.style = style; ohair@286: } ohair@286: mkos@384: @Override mkos@408: public @Nullable QName getRequestPayloadName() { ohair@286: if (emptyRequestPayload) ohair@286: return null; ohair@286: ohair@286: if (requestPayloadName != null) ohair@286: return requestPayloadName; ohair@286: ohair@286: if(style.equals(Style.RPC)){ ohair@286: String ns = getRequestNamespace() != null ? getRequestNamespace() : name.getNamespaceURI(); ohair@286: requestPayloadName = new QName(ns, name.getLocalPart()); ohair@286: return requestPayloadName; ohair@286: }else{ ohair@286: QName inMsgName = operation.getInput().getMessage().getName(); mkos@408: EditableWSDLMessage message = messages.get(inMsgName); mkos@408: for(EditableWSDLPart part:message.parts()){ ohair@286: ParameterBinding binding = getInputBinding(part.getName()); ohair@286: if(binding.isBody()){ ohair@286: requestPayloadName = part.getDescriptor().name(); ohair@286: return requestPayloadName; ohair@286: } ohair@286: } ohair@286: ohair@286: //Its empty payload ohair@286: emptyRequestPayload = true; ohair@286: } ohair@286: //empty body ohair@286: return null; ohair@286: } ohair@286: mkos@384: @Override mkos@408: public @Nullable QName getResponsePayloadName() { ohair@286: if (emptyResponsePayload) ohair@286: return null; ohair@286: ohair@286: if (responsePayloadName != null) ohair@286: return responsePayloadName; ohair@286: ohair@286: if(style.equals(Style.RPC)){ ohair@286: String ns = getResponseNamespace() != null ? getResponseNamespace() : name.getNamespaceURI(); ohair@286: responsePayloadName = new QName(ns, name.getLocalPart()+"Response"); ohair@286: return responsePayloadName; ohair@286: }else{ ohair@286: QName outMsgName = operation.getOutput().getMessage().getName(); mkos@408: EditableWSDLMessage message = messages.get(outMsgName); mkos@408: for(EditableWSDLPart part:message.parts()){ ohair@286: ParameterBinding binding = getOutputBinding(part.getName()); ohair@286: if(binding.isBody()){ ohair@286: responsePayloadName = part.getDescriptor().name(); ohair@286: return responsePayloadName; ohair@286: } ohair@286: } ohair@286: ohair@286: //Its empty payload ohair@286: emptyResponsePayload = true; ohair@286: } ohair@286: //empty body ohair@286: return null; ohair@286: } ohair@286: ohair@286: ohair@286: private String reqNamespace; ohair@286: private String respNamespace; ohair@286: ohair@286: /** ohair@286: * For rpclit gives namespace value on soapbinding:body@namespace ohair@286: * ohair@286: * @return non-null for rpclit and null for doclit alanb@368: * @see RuntimeModeler#processRpcMethod(JavaMethodImpl, String, String, Method) ohair@286: */ mkos@384: @Override ohair@286: public String getRequestNamespace(){ ohair@286: return (reqNamespace != null)?reqNamespace:name.getNamespaceURI(); ohair@286: } ohair@286: ohair@286: public void setRequestNamespace(String ns){ ohair@286: reqNamespace = ns; ohair@286: } ohair@286: ohair@286: /** ohair@286: * For rpclit gives namespace value on soapbinding:body@namespace ohair@286: * ohair@286: * @return non-null for rpclit and null for doclit alanb@368: * @see RuntimeModeler#processRpcMethod(JavaMethodImpl, String, String, Method) ohair@286: */ mkos@384: @Override ohair@286: public String getResponseNamespace(){ ohair@286: return (respNamespace!=null)?respNamespace:name.getNamespaceURI(); ohair@286: } ohair@286: ohair@286: public void setResponseNamespace(String ns){ ohair@286: respNamespace = ns; ohair@286: } ohair@286: mkos@408: EditableWSDLBoundPortType getOwner(){ ohair@286: return owner; ohair@286: } ohair@286: ohair@286: private QName requestPayloadName; ohair@286: private QName responsePayloadName; ohair@286: private boolean emptyRequestPayload; ohair@286: private boolean emptyResponsePayload; mkos@408: private Map messages; ohair@286: mkos@408: public void freeze(EditableWSDLModel parent) { ohair@286: messages = parent.getMessages(); ohair@286: operation = owner.getPortType().get(name.getLocalPart()); mkos@408: for(EditableWSDLBoundFault bf : wsdlBoundFaults){ ohair@286: bf.freeze(this); ohair@286: } ohair@286: } ohair@286: ohair@286: public void setAnonymous(ANONYMOUS anonymous) { ohair@286: this.anonymous = anonymous; ohair@286: } ohair@286: ohair@286: /** ohair@286: * @inheritDoc ohair@286: */ mkos@384: @Override ohair@286: public ANONYMOUS getAnonymous() { ohair@286: return anonymous; ohair@286: } ohair@286: }