001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036: package com.sun.xml.ws.model.wsdl;
037:
038: import com.sun.istack.NotNull;
039: import com.sun.xml.ws.api.BindingID;
040: import com.sun.xml.ws.api.SOAPVersion;
041: import com.sun.xml.ws.api.model.ParameterBinding;
042: import com.sun.xml.ws.api.model.wsdl.WSDLBoundOperation;
043: import com.sun.xml.ws.api.model.wsdl.WSDLBoundPortType;
044: import com.sun.xml.ws.resources.ClientMessages;
045: import com.sun.xml.ws.util.QNameMap;
046: import com.sun.xml.ws.util.exception.LocatableWebServiceException;
047:
048: import javax.jws.WebParam.Mode;
049: import javax.jws.soap.SOAPBinding;
050: import javax.jws.soap.SOAPBinding.Style;
051: import javax.xml.namespace.QName;
052: import javax.xml.stream.XMLStreamReader;
053: import javax.xml.ws.soap.MTOMFeature;
054:
055: /**
056: * Implementation of {@link WSDLBoundPortType}
057: *
058: * @author Vivek Pandey
059: */
060: public final class WSDLBoundPortTypeImpl extends
061: AbstractFeaturedObjectImpl implements WSDLBoundPortType {
062: private final QName name;
063: private final QName portTypeName;
064: private WSDLPortTypeImpl portType;
065: private BindingID bindingId;
066: private final @NotNull
067: WSDLModelImpl owner;
068: private final QNameMap<WSDLBoundOperationImpl> bindingOperations = new QNameMap<WSDLBoundOperationImpl>();
069:
070: /**
071: * Operations keyed by the payload tag name.
072: */
073: private QNameMap<WSDLBoundOperationImpl> payloadMap;
074: /**
075: * {@link #payloadMap} doesn't allow null key, so we store the value for it here.
076: */
077: private WSDLBoundOperationImpl emptyPayloadOperation;
078:
079: public WSDLBoundPortTypeImpl(XMLStreamReader xsr, @NotNull
080: WSDLModelImpl owner, QName name, QName portTypeName) {
081: super (xsr);
082: this .owner = owner;
083: this .name = name;
084: this .portTypeName = portTypeName;
085: owner.addBinding(this );
086: }
087:
088: public QName getName() {
089: return name;
090: }
091:
092: public @NotNull
093: WSDLModelImpl getOwner() {
094: return owner;
095: }
096:
097: public WSDLBoundOperationImpl get(QName operationName) {
098: return bindingOperations.get(operationName);
099: }
100:
101: /**
102: * Populates the Map that holds operation name as key and {@link WSDLBoundOperation} as the value.
103: *
104: * @param opName Must be non-null
105: * @param ptOp Must be non-null
106: * @throws NullPointerException if either opName or ptOp is null
107: */
108: public void put(QName opName, WSDLBoundOperationImpl ptOp) {
109: bindingOperations.put(opName, ptOp);
110: }
111:
112: public QName getPortTypeName() {
113: return portTypeName;
114: }
115:
116: public WSDLPortTypeImpl getPortType() {
117: return portType;
118: }
119:
120: public Iterable<WSDLBoundOperationImpl> getBindingOperations() {
121: return bindingOperations.values();
122: }
123:
124: public BindingID getBindingId() {
125: //Should the default be SOAP1.1/HTTP binding? For now lets keep it for
126: //JBI bug 6509800
127: return (bindingId == null) ? BindingID.SOAP11_HTTP : bindingId;
128: }
129:
130: public void setBindingId(BindingID bindingId) {
131: this .bindingId = bindingId;
132: }
133:
134: /**
135: * sets whether the {@link WSDLBoundPortType} is rpc or lit
136: */
137: private Style style = Style.DOCUMENT;
138:
139: public void setStyle(Style style) {
140: this .style = style;
141: }
142:
143: public SOAPBinding.Style getStyle() {
144: return style;
145: }
146:
147: public boolean isRpcLit() {
148: return Style.RPC == style;
149: }
150:
151: public boolean isDoclit() {
152: return Style.DOCUMENT == style;
153: }
154:
155: /**
156: * Gets the {@link ParameterBinding} for a given operation, part name and the direction - IN/OUT
157: *
158: * @param operation wsdl:operation@name value. Must be non-null.
159: * @param part wsdl:part@name such as value of soap:header@part. Must be non-null.
160: * @param mode {@link Mode#IN} or {@link Mode@OUT}. Must be non-null.
161: * @return null if the binding could not be resolved for the part.
162: */
163: public ParameterBinding getBinding(QName operation, String part,
164: Mode mode) {
165: WSDLBoundOperationImpl op = get(operation);
166: if (op == null) {
167: //TODO throw exception
168: return null;
169: }
170: if ((Mode.IN == mode) || (Mode.INOUT == mode))
171: return op.getInputBinding(part);
172: else
173: return op.getOutputBinding(part);
174: }
175:
176: /**
177: * Gets mime:content@part value which is the MIME type for a given operation, part and {@link Mode}.
178: *
179: * @param operation wsdl:operation@name value. Must be non-null.
180: * @param part wsdl:part@name such as value of soap:header@part. Must be non-null.
181: * @param mode {@link Mode#IN} or {@link Mode@OUT}. Must be non-null.
182: * @return null if the binding could not be resolved for the part.
183: */
184: public String getMimeType(QName operation, String part, Mode mode) {
185: WSDLBoundOperationImpl op = get(operation);
186: if (Mode.IN == mode)
187: return op.getMimeTypeForInputPart(part);
188: else
189: return op.getMimeTypeForOutputPart(part);
190: }
191:
192: public WSDLBoundOperationImpl getOperation(String namespaceUri,
193: String localName) {
194: if (namespaceUri == null && localName == null)
195: return emptyPayloadOperation;
196: else {
197: return payloadMap.get((namespaceUri == null) ? ""
198: : namespaceUri, localName);
199: }
200: }
201:
202: public void enableMTOM() {
203: features.add(new MTOMFeature());
204: }
205:
206: public boolean isMTOMEnabled() {
207: return features.isEnabled(MTOMFeature.class);
208: }
209:
210: public SOAPVersion getSOAPVersion() {
211: return getBindingId().getSOAPVersion();
212: }
213:
214: void freeze() {
215: portType = owner.getPortType(portTypeName);
216: if (portType == null) {
217: throw new LocatableWebServiceException(ClientMessages
218: .UNDEFINED_PORT_TYPE(portTypeName), getLocation());
219: }
220: portType.freeze();
221:
222: for (WSDLBoundOperationImpl op : bindingOperations.values()) {
223: op.freeze(owner);
224: }
225:
226: freezePayloadMap();
227: owner.finalizeRpcLitBinding(this );
228: }
229:
230: private void freezePayloadMap() {
231: if (style == Style.RPC) {
232: // If the style is rpc then the tag name should be
233: // same as operation name so return the operation that matches the tag name.
234: payloadMap = bindingOperations;
235: } else {
236: payloadMap = new QNameMap<WSDLBoundOperationImpl>();
237: // For doclit The tag will be the operation that has the same input part descriptor value
238: for (WSDLBoundOperationImpl op : bindingOperations.values()) {
239: QName name = op.getPayloadName();
240: if (name == null) {
241: //empty payload
242: emptyPayloadOperation = op;
243: continue;
244: }
245:
246: payloadMap.put(name, op);
247: }
248: }
249: }
250: }
|