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.Nullable;
039: import com.sun.istack.NotNull;
040: import com.sun.xml.ws.api.model.ParameterBinding;
041: import com.sun.xml.ws.api.model.wsdl.*;
042:
043: import javax.jws.WebParam.Mode;
044: import javax.jws.soap.SOAPBinding.Style;
045: import javax.xml.namespace.QName;
046: import javax.xml.stream.XMLStreamReader;
047: import java.util.*;
048:
049: /**
050: * Implementation of {@link WSDLBoundOperation}
051: *
052: * @author Vivek Pandey
053: */
054: public final class WSDLBoundOperationImpl extends
055: AbstractExtensibleImpl implements WSDLBoundOperation {
056: private final QName name;
057:
058: // map of wsdl:part to the binding
059: private final Map<String, ParameterBinding> inputParts;
060: private final Map<String, ParameterBinding> outputParts;
061: private final Map<String, ParameterBinding> faultParts;
062: private final Map<String, String> inputMimeTypes;
063: private final Map<String, String> outputMimeTypes;
064: private final Map<String, String> faultMimeTypes;
065:
066: private boolean explicitInputSOAPBodyParts = false;
067: private boolean explicitOutputSOAPBodyParts = false;
068: private boolean explicitFaultSOAPBodyParts = false;
069:
070: private Boolean emptyInputBody;
071: private Boolean emptyOutputBody;
072: private Boolean emptyFaultBody;
073:
074: private final Map<String, WSDLPartImpl> inParts;
075: private final Map<String, WSDLPartImpl> outParts;
076: private final Map<String, WSDLPartImpl> fltParts;
077: private final List<WSDLBoundFaultImpl> wsdlBoundFaults;
078: private WSDLOperationImpl operation;
079: private String soapAction;
080: private ANONYMOUS anonymous;
081:
082: private final WSDLBoundPortTypeImpl owner;
083:
084: /**
085: *
086: * @param name wsdl:operation name qualified value
087: */
088: public WSDLBoundOperationImpl(XMLStreamReader xsr,
089: WSDLBoundPortTypeImpl owner, QName name) {
090: super (xsr);
091: this .name = name;
092: inputParts = new HashMap<String, ParameterBinding>();
093: outputParts = new HashMap<String, ParameterBinding>();
094: faultParts = new HashMap<String, ParameterBinding>();
095: inputMimeTypes = new HashMap<String, String>();
096: outputMimeTypes = new HashMap<String, String>();
097: faultMimeTypes = new HashMap<String, String>();
098: inParts = new HashMap<String, WSDLPartImpl>();
099: outParts = new HashMap<String, WSDLPartImpl>();
100: fltParts = new HashMap<String, WSDLPartImpl>();
101: wsdlBoundFaults = new ArrayList<WSDLBoundFaultImpl>();
102: this .owner = owner;
103: }
104:
105: public QName getName() {
106: return name;
107: }
108:
109: public String getSOAPAction() {
110: return soapAction;
111: }
112:
113: public void setSoapAction(String soapAction) {
114: this .soapAction = soapAction != null ? soapAction : "";
115: }
116:
117: public WSDLPartImpl getPart(String partName, Mode mode) {
118: if (mode == Mode.IN) {
119: return inParts.get(partName);
120: } else if (mode == Mode.OUT) {
121: return outParts.get(partName);
122: }
123: return null;
124: }
125:
126: public void addPart(WSDLPartImpl part, Mode mode) {
127: if (mode == Mode.IN)
128: inParts.put(part.getName(), part);
129: else if (mode == Mode.OUT)
130: outParts.put(part.getName(), part);
131: }
132:
133: /**
134: * Map of wsdl:input part name and the binding as {@link ParameterBinding}
135: *
136: * @return empty Map if there is no parts
137: */
138: public Map<String, ParameterBinding> getInputParts() {
139: return inputParts;
140: }
141:
142: /**
143: * Map of wsdl:output part name and the binding as {@link ParameterBinding}
144: *
145: * @return empty Map if there is no parts
146: */
147: public Map<String, ParameterBinding> getOutputParts() {
148: return outputParts;
149: }
150:
151: /**
152: * Map of wsdl:fault part name and the binding as {@link ParameterBinding}
153: *
154: * @return empty Map if there is no parts
155: */
156: public Map<String, ParameterBinding> getFaultParts() {
157: return faultParts;
158: }
159:
160: // TODO: what's the difference between this and inputParts/outputParts?
161: public Map<String, WSDLPart> getInParts() {
162: return Collections.<String, WSDLPart> unmodifiableMap(inParts);
163: }
164:
165: public Map<String, WSDLPart> getOutParts() {
166: return Collections.<String, WSDLPart> unmodifiableMap(outParts);
167: }
168:
169: @NotNull
170: public List<WSDLBoundFaultImpl> getFaults() {
171: return wsdlBoundFaults;
172: }
173:
174: public void addFault(@NotNull
175: WSDLBoundFaultImpl fault) {
176: wsdlBoundFaults.add(fault);
177: }
178:
179: /**
180: * Map of mime:content@part and the mime type from mime:content@type for wsdl:output
181: *
182: * @return empty Map if there is no parts
183: */
184: public Map<String, String> getInputMimeTypes() {
185: return inputMimeTypes;
186: }
187:
188: /**
189: * Map of mime:content@part and the mime type from mime:content@type for wsdl:output
190: *
191: * @return empty Map if there is no parts
192: */
193: public Map<String, String> getOutputMimeTypes() {
194: return outputMimeTypes;
195: }
196:
197: /**
198: * Map of mime:content@part and the mime type from mime:content@type for wsdl:fault
199: *
200: * @return empty Map if there is no parts
201: */
202: public Map<String, String> getFaultMimeTypes() {
203: return faultMimeTypes;
204: }
205:
206: /**
207: * Gets {@link ParameterBinding} for a given wsdl part in wsdl:input
208: *
209: * @param part Name of wsdl:part, must be non-null
210: * @return null if the part is not found.
211: */
212: public ParameterBinding getInputBinding(String part) {
213: if (emptyInputBody == null) {
214: if (inputParts.get(" ") != null)
215: emptyInputBody = true;
216: else
217: emptyInputBody = false;
218: }
219: ParameterBinding block = inputParts.get(part);
220: if (block == null) {
221: if (explicitInputSOAPBodyParts || emptyInputBody)
222: return ParameterBinding.UNBOUND;
223: return ParameterBinding.BODY;
224: }
225:
226: return block;
227: }
228:
229: /**
230: * Gets {@link ParameterBinding} for a given wsdl part in wsdl:output
231: *
232: * @param part Name of wsdl:part, must be non-null
233: * @return null if the part is not found.
234: */
235: public ParameterBinding getOutputBinding(String part) {
236: if (emptyOutputBody == null) {
237: if (outputParts.get(" ") != null)
238: emptyOutputBody = true;
239: else
240: emptyOutputBody = false;
241: }
242: ParameterBinding block = outputParts.get(part);
243: if (block == null) {
244: if (explicitOutputSOAPBodyParts || emptyOutputBody)
245: return ParameterBinding.UNBOUND;
246: return ParameterBinding.BODY;
247: }
248:
249: return block;
250: }
251:
252: /**
253: * Gets {@link ParameterBinding} for a given wsdl part in wsdl:fault
254: *
255: * @param part Name of wsdl:part, must be non-null
256: * @return null if the part is not found.
257: */
258: public ParameterBinding getFaultBinding(String part) {
259: if (emptyFaultBody == null) {
260: if (faultParts.get(" ") != null)
261: emptyFaultBody = true;
262: else
263: emptyFaultBody = false;
264: }
265: ParameterBinding block = faultParts.get(part);
266: if (block == null) {
267: if (explicitFaultSOAPBodyParts || emptyFaultBody)
268: return ParameterBinding.UNBOUND;
269: return ParameterBinding.BODY;
270: }
271:
272: return block;
273: }
274:
275: /**
276: * Gets the MIME type for a given wsdl part in wsdl:input
277: *
278: * @param part Name of wsdl:part, must be non-null
279: * @return null if the part is not found.
280: */
281: public String getMimeTypeForInputPart(String part) {
282: return inputMimeTypes.get(part);
283: }
284:
285: /**
286: * Gets the MIME type for a given wsdl part in wsdl:output
287: *
288: * @param part Name of wsdl:part, must be non-null
289: * @return null if the part is not found.
290: */
291: public String getMimeTypeForOutputPart(String part) {
292: return outputMimeTypes.get(part);
293: }
294:
295: /**
296: * Gets the MIME type for a given wsdl part in wsdl:fault
297: *
298: * @param part Name of wsdl:part, must be non-null
299: * @return null if the part is not found.
300: */
301: public String getMimeTypeForFaultPart(String part) {
302: return faultMimeTypes.get(part);
303: }
304:
305: public WSDLOperationImpl getOperation() {
306: return operation;
307: }
308:
309: public void setInputExplicitBodyParts(boolean b) {
310: explicitInputSOAPBodyParts = b;
311: }
312:
313: public void setOutputExplicitBodyParts(boolean b) {
314: explicitOutputSOAPBodyParts = b;
315: }
316:
317: public void setFaultExplicitBodyParts(boolean b) {
318: explicitFaultSOAPBodyParts = b;
319: }
320:
321: private Style style = Style.DOCUMENT;
322:
323: public void setStyle(Style style) {
324: this .style = style;
325: }
326:
327: public @Nullable
328: QName getPayloadName() {
329: if (style.equals(Style.RPC)) {
330: return name;
331: } else {
332: if (emptyPayload)
333: return null;
334:
335: if (payloadName != null)
336: return payloadName;
337:
338: QName inMsgName = operation.getInput().getMessage()
339: .getName();
340: WSDLMessageImpl message = messages.get(inMsgName);
341: for (WSDLPartImpl part : message.parts()) {
342: ParameterBinding binding = getInputBinding(part
343: .getName());
344: if (binding.isBody()) {
345: payloadName = part.getDescriptor().name();
346: return payloadName;
347: }
348: }
349:
350: //Its empty payload
351: emptyPayload = true;
352: }
353: //empty body
354: return null;
355: }
356:
357: public @Nullable
358: QName getReqPayloadName() {
359: if (emptyRequestPayload)
360: return null;
361:
362: if (requestPayloadName != null)
363: return requestPayloadName;
364:
365: if (style.equals(Style.RPC)) {
366: String ns = getRequestNamespace() != null ? getRequestNamespace()
367: : name.getNamespaceURI();
368: requestPayloadName = new QName(ns, name.getLocalPart());
369: return requestPayloadName;
370: } else {
371: QName inMsgName = operation.getInput().getMessage()
372: .getName();
373: WSDLMessageImpl message = messages.get(inMsgName);
374: for (WSDLPartImpl part : message.parts()) {
375: ParameterBinding binding = getInputBinding(part
376: .getName());
377: if (binding.isBody()) {
378: requestPayloadName = part.getDescriptor().name();
379: return requestPayloadName;
380: }
381: }
382:
383: //Its empty payload
384: emptyRequestPayload = true;
385: }
386: //empty body
387: return null;
388: }
389:
390: public @Nullable
391: QName getResPayloadName() {
392: if (emptyResponsePayload)
393: return null;
394:
395: if (responsePayloadName != null)
396: return responsePayloadName;
397:
398: if (style.equals(Style.RPC)) {
399: String ns = getResponseNamespace() != null ? getResponseNamespace()
400: : name.getNamespaceURI();
401: responsePayloadName = new QName(ns, name.getLocalPart()
402: + "Response");
403: return responsePayloadName;
404: } else {
405: QName outMsgName = operation.getOutput().getMessage()
406: .getName();
407: WSDLMessageImpl message = messages.get(outMsgName);
408: for (WSDLPartImpl part : message.parts()) {
409: ParameterBinding binding = getOutputBinding(part
410: .getName());
411: if (binding.isBody()) {
412: responsePayloadName = part.getDescriptor().name();
413: return responsePayloadName;
414: }
415: }
416:
417: //Its empty payload
418: emptyResponsePayload = true;
419: }
420: //empty body
421: return null;
422: }
423:
424: private String reqNamespace;
425: private String respNamespace;
426:
427: /**
428: * For rpclit gives namespace value on soapbinding:body@namespace
429: *
430: * @return non-null for rpclit and null for doclit
431: * @see com.sun.xml.ws.model.RuntimeModeler#processRpcMethod(com.sun.xml.ws.model.JavaMethodImpl, String, javax.jws.WebMethod, String, java.lang.reflect.Method, javax.jws.WebService)
432: */
433: public String getRequestNamespace() {
434: return (reqNamespace != null) ? reqNamespace : name
435: .getNamespaceURI();
436: }
437:
438: public void setRequestNamespace(String ns) {
439: reqNamespace = ns;
440: }
441:
442: /**
443: * For rpclit gives namespace value on soapbinding:body@namespace
444: *
445: * @return non-null for rpclit and null for doclit
446: * * @see com.sun.xml.ws.modeler.RuntimeModeler#processRpcMethod(com.sun.xml.ws.model.JavaMethod, String, javax.jws.WebMethod, String, java.lang.reflect.Method, javax.jws.WebService)
447: */
448: public String getResponseNamespace() {
449: return (respNamespace != null) ? respNamespace : name
450: .getNamespaceURI();
451: }
452:
453: public void setResponseNamespace(String ns) {
454: respNamespace = ns;
455: }
456:
457: WSDLBoundPortTypeImpl getOwner() {
458: return owner;
459: }
460:
461: private QName payloadName;
462: private QName requestPayloadName;
463: private QName responsePayloadName;
464: private boolean emptyPayload;
465: private boolean emptyRequestPayload;
466: private boolean emptyResponsePayload;
467: private Map<QName, WSDLMessageImpl> messages;
468:
469: void freeze(WSDLModelImpl parent) {
470: messages = parent.getMessages();
471: operation = owner.getPortType().get(name.getLocalPart());
472: for (WSDLBoundFaultImpl bf : wsdlBoundFaults) {
473: bf.freeze(this );
474: }
475: }
476:
477: public void setAnonymous(ANONYMOUS anonymous) {
478: this .anonymous = anonymous;
479: }
480:
481: /**
482: * @inheritDoc
483: */
484: public ANONYMOUS getAnonymous() {
485: return anonymous;
486: }
487: }
|