001: /*
002: * soapUI, copyright (C) 2004-2007 eviware.com
003: *
004: * soapUI is free software; you can redistribute it and/or modify it under the
005: * terms of version 2.1 of the GNU Lesser General Public License as published by
006: * the Free Software Foundation.
007: *
008: * soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009: * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
010: * See the GNU Lesser General Public License for more details at gnu.org.
011: */
012:
013: package com.eviware.soapui.impl.wsdl.support.wsdl;
014:
015: import java.util.ArrayList;
016: import java.util.Iterator;
017: import java.util.List;
018: import java.util.Map;
019:
020: import javax.wsdl.Binding;
021: import javax.wsdl.BindingFault;
022: import javax.wsdl.BindingOperation;
023: import javax.wsdl.BindingOutput;
024: import javax.wsdl.Definition;
025: import javax.wsdl.Fault;
026: import javax.wsdl.Message;
027: import javax.wsdl.Operation;
028: import javax.wsdl.Part;
029: import javax.wsdl.Port;
030: import javax.wsdl.Service;
031: import javax.wsdl.extensions.ExtensibilityElement;
032: import javax.wsdl.extensions.mime.MIMEContent;
033: import javax.wsdl.extensions.mime.MIMEMultipartRelated;
034: import javax.wsdl.extensions.mime.MIMEPart;
035: import javax.wsdl.extensions.soap.SOAPAddress;
036: import javax.wsdl.extensions.soap.SOAPBinding;
037: import javax.wsdl.extensions.soap.SOAPBody;
038: import javax.wsdl.extensions.soap.SOAPFault;
039: import javax.wsdl.extensions.soap.SOAPHeader;
040: import javax.wsdl.extensions.soap.SOAPOperation;
041: import javax.wsdl.extensions.soap12.SOAP12Address;
042: import javax.wsdl.extensions.soap12.SOAP12Binding;
043: import javax.wsdl.extensions.soap12.SOAP12Body;
044: import javax.wsdl.extensions.soap12.SOAP12Fault;
045: import javax.wsdl.extensions.soap12.SOAP12Header;
046: import javax.wsdl.extensions.soap12.SOAP12Operation;
047: import javax.wsdl.factory.WSDLFactory;
048: import javax.wsdl.xml.WSDLReader;
049: import javax.xml.namespace.QName;
050:
051: import org.apache.log4j.Logger;
052: import org.apache.xmlbeans.SchemaGlobalElement;
053: import org.apache.xmlbeans.SchemaType;
054:
055: import com.eviware.soapui.impl.wsdl.WsdlRequest;
056:
057: /**
058: * Wsdl-related tools
059: *
060: * @author Ole.Matzura
061: */
062:
063: public class WsdlUtils {
064: private final static Logger log = Logger.getLogger(WsdlUtils.class);
065: private static WSDLReader wsdlReader;
066:
067: public static <T extends ExtensibilityElement> T getExtensiblityElement(
068: List list, Class<T> clazz) {
069: List<T> elements = getExtensiblityElements(list, clazz);
070: return elements.isEmpty() ? null : elements.get(0);
071: }
072:
073: public static <T extends ExtensibilityElement> List<T> getExtensiblityElements(
074: List list, Class<T> clazz) {
075: List<T> result = new ArrayList<T>();
076:
077: for (Iterator<T> i = list.iterator(); i.hasNext();) {
078: T elm = (T) i.next();
079: if (clazz.isAssignableFrom(elm.getClass())) {
080: result.add(elm);
081: }
082: }
083:
084: return result;
085: }
086:
087: public static String getSoapAction(BindingOperation operation) {
088: List list = operation.getExtensibilityElements();
089: SOAPOperation soapOperation = (SOAPOperation) WsdlUtils
090: .getExtensiblityElement(list, SOAPOperation.class);
091: if (soapOperation != null)
092: return soapOperation.getSoapActionURI();
093:
094: SOAP12Operation soap12Operation = (SOAP12Operation) WsdlUtils
095: .getExtensiblityElement(list, SOAP12Operation.class);
096: if (soap12Operation != null)
097: return soap12Operation.getSoapActionURI();
098:
099: return null;
100: }
101:
102: public static String[] getEndpointsForBinding(
103: Definition definition, Binding binding) {
104: List<String> result = new ArrayList<String>();
105: Map map = definition.getAllServices();
106: for (Iterator i = map.values().iterator(); i.hasNext();) {
107: Service service = (Service) i.next();
108: Map portMap = service.getPorts();
109: for (Iterator i2 = portMap.values().iterator(); i2
110: .hasNext();) {
111: Port port = (Port) i2.next();
112: if (port.getBinding() == binding) {
113: String endpoint = WsdlUtils.getSoapEndpoint(port);
114: if (endpoint != null)
115: result.add(endpoint);
116: }
117: }
118: }
119:
120: return result.toArray(new String[result.size()]);
121: }
122:
123: public static Binding findBindingForOperation(
124: Definition definition, BindingOperation bindingOperation) {
125: Map services = definition.getAllServices();
126: Iterator<Service> s = services.values().iterator();
127:
128: while (s.hasNext()) {
129: Map ports = s.next().getPorts();
130: Iterator<Port> p = ports.values().iterator();
131: while (p.hasNext()) {
132: Binding binding = p.next().getBinding();
133: List bindingOperations = binding.getBindingOperations();
134: for (Iterator iter = bindingOperations.iterator(); iter
135: .hasNext();) {
136: BindingOperation op = (BindingOperation) iter
137: .next();
138: if (op.getName().equals(bindingOperation.getName()))
139: return binding;
140: }
141: }
142: }
143:
144: Map bindings = definition.getAllBindings();
145: Iterator<QName> names = bindings.keySet().iterator();
146: while (names.hasNext()) {
147: Binding binding = definition.getBinding(names.next());
148: List bindingOperations = binding.getBindingOperations();
149: for (Iterator iter = bindingOperations.iterator(); iter
150: .hasNext();) {
151: BindingOperation op = (BindingOperation) iter.next();
152: if (op.getName().equals(bindingOperation.getName()))
153: return binding;
154: }
155: }
156:
157: return null;
158: }
159:
160: public static boolean isInputSoapEncoded(
161: BindingOperation bindingOperation) {
162: SOAPBody soapBody = (SOAPBody) WsdlUtils
163: .getExtensiblityElement(bindingOperation
164: .getBindingInput().getExtensibilityElements(),
165: SOAPBody.class);
166:
167: if (soapBody != null) {
168: return soapBody.getUse() != null
169: && soapBody.getUse().equalsIgnoreCase("encoded")
170: && (soapBody.getEncodingStyles() == null || soapBody
171: .getEncodingStyles()
172: .contains(
173: "http://schemas.xmlsoap.org/soap/encoding/"));
174: }
175:
176: SOAP12Body soap12Body = (SOAP12Body) WsdlUtils
177: .getExtensiblityElement(bindingOperation
178: .getBindingInput().getExtensibilityElements(),
179: SOAP12Body.class);
180:
181: if (soap12Body != null) {
182: return soap12Body.getUse() != null
183: && soap12Body.getUse().equalsIgnoreCase("encoded")
184: && (soap12Body.getEncodingStyle() == null || soap12Body
185: .getEncodingStyle()
186: .equals(
187: "http://schemas.xmlsoap.org/soap/encoding/"));
188: }
189:
190: return false;
191: }
192:
193: public static boolean isOutputSoapEncoded(
194: BindingOperation bindingOperation) {
195: BindingOutput bindingOutput = bindingOperation
196: .getBindingOutput();
197: if (bindingOutput == null)
198: return false;
199:
200: SOAPBody soapBody = (SOAPBody) WsdlUtils
201: .getExtensiblityElement(bindingOutput
202: .getExtensibilityElements(), SOAPBody.class);
203:
204: if (soapBody != null) {
205: return soapBody.getUse() != null
206: && soapBody.getUse().equalsIgnoreCase("encoded")
207: && (soapBody.getEncodingStyles() == null || soapBody
208: .getEncodingStyles()
209: .contains(
210: "http://schemas.xmlsoap.org/soap/encoding/"));
211: }
212:
213: SOAP12Body soap12Body = (SOAP12Body) WsdlUtils
214: .getExtensiblityElement(bindingOutput
215: .getExtensibilityElements(), SOAP12Body.class);
216:
217: if (soap12Body != null) {
218: return soap12Body.getUse() != null
219: && soap12Body.getUse().equalsIgnoreCase("encoded")
220: && (soap12Body.getEncodingStyle() == null || soap12Body
221: .getEncodingStyle()
222: .equals(
223: "http://schemas.xmlsoap.org/soap/encoding/"));
224: }
225:
226: return false;
227: }
228:
229: public static boolean isRpc(Definition definition,
230: BindingOperation bindingOperation) {
231: SOAPOperation soapOperation = (SOAPOperation) WsdlUtils
232: .getExtensiblityElement(bindingOperation
233: .getExtensibilityElements(),
234: SOAPOperation.class);
235:
236: if (soapOperation != null && soapOperation.getStyle() != null)
237: return soapOperation.getStyle().equalsIgnoreCase("rpc");
238:
239: SOAP12Operation soap12Operation = (SOAP12Operation) WsdlUtils
240: .getExtensiblityElement(bindingOperation
241: .getExtensibilityElements(),
242: SOAP12Operation.class);
243:
244: if (soap12Operation != null
245: && soap12Operation.getStyle() != null)
246: return soap12Operation.getStyle().equalsIgnoreCase("rpc");
247:
248: Binding binding = findBindingForOperation(definition,
249: bindingOperation);
250: if (binding == null) {
251: log.error("Failed to find binding for operation ["
252: + bindingOperation.getName() + "] in definition ["
253: + definition.getDocumentBaseURI() + "]");
254: return false;
255: }
256:
257: return isRpc(binding);
258: }
259:
260: public static boolean isRpc(Binding binding) {
261: SOAPBinding soapBinding = (SOAPBinding) WsdlUtils
262: .getExtensiblityElement(binding
263: .getExtensibilityElements(), SOAPBinding.class);
264:
265: if (soapBinding != null)
266: return "rpc".equalsIgnoreCase(soapBinding.getStyle());
267:
268: SOAP12Binding soap12Binding = (SOAP12Binding) WsdlUtils
269: .getExtensiblityElement(binding
270: .getExtensibilityElements(),
271: SOAP12Binding.class);
272:
273: if (soap12Binding != null)
274: return "rpc".equalsIgnoreCase(soap12Binding.getStyle());
275:
276: return false;
277: }
278:
279: /**
280: * Returns a list of parts for the specifed operation, either as specified in body or all
281: */
282:
283: public static Part[] getInputParts(BindingOperation operation) {
284: List<Part> result = new ArrayList<Part>();
285: Message msg = operation.getOperation().getInput().getMessage();
286: SOAPBody soapBody = (SOAPBody) WsdlUtils
287: .getExtensiblityElement(operation.getBindingInput()
288: .getExtensibilityElements(), SOAPBody.class);
289:
290: if (soapBody == null || soapBody.getParts() == null) {
291: SOAP12Body soap12Body = (SOAP12Body) WsdlUtils
292: .getExtensiblityElement(operation.getBindingInput()
293: .getExtensibilityElements(),
294: SOAP12Body.class);
295:
296: if (soap12Body == null || soap12Body.getParts() == null) {
297: if (msg != null)
298: result.addAll(msg.getOrderedParts(null));
299: } else {
300: Iterator i = soap12Body.getParts().iterator();
301: while (i.hasNext()) {
302: String partName = (String) i.next();
303: Part part = msg.getPart(partName);
304:
305: result.add(part);
306: }
307: }
308: } else {
309: Iterator i = soapBody.getParts().iterator();
310: while (i.hasNext()) {
311: String partName = (String) i.next();
312: Part part = msg.getPart(partName);
313:
314: result.add(part);
315: }
316: }
317:
318: return result.toArray(new Part[result.size()]);
319: }
320:
321: public static boolean isAttachmentInputPart(Part part,
322: BindingOperation operation) {
323: return getInputMultipartContent(part, operation).length > 0;
324: }
325:
326: public static boolean isAttachmentOutputPart(Part part,
327: BindingOperation operation) {
328: return getOutputMultipartContent(part, operation).length > 0;
329: }
330:
331: public static MIMEContent[] getOutputMultipartContent(Part part,
332: BindingOperation operation) {
333: MIMEMultipartRelated multipartOutput = (MIMEMultipartRelated) WsdlUtils
334: .getExtensiblityElement(operation.getBindingOutput()
335: .getExtensibilityElements(),
336: MIMEMultipartRelated.class);
337:
338: return getContentParts(part, multipartOutput);
339: }
340:
341: public static MIMEContent[] getInputMultipartContent(Part part,
342: BindingOperation operation) {
343: MIMEMultipartRelated multipartInput = (MIMEMultipartRelated) WsdlUtils
344: .getExtensiblityElement(operation.getBindingInput()
345: .getExtensibilityElements(),
346: MIMEMultipartRelated.class);
347:
348: return getContentParts(part, multipartInput);
349: }
350:
351: public static MIMEContent[] getContentParts(Part part,
352: MIMEMultipartRelated multipart) {
353: List<MIMEContent> result = new ArrayList<MIMEContent>();
354:
355: if (multipart != null) {
356: List<MIMEPart> parts = multipart.getMIMEParts();
357:
358: for (int c = 0; c < parts.size(); c++) {
359: List<MIMEContent> contentParts = WsdlUtils
360: .getExtensiblityElements(parts.get(c)
361: .getExtensibilityElements(),
362: MIMEContent.class);
363:
364: for (MIMEContent content : contentParts) {
365: if (content.getPart().equals(part.getName()))
366: result.add(content);
367: }
368: }
369: }
370:
371: return result.toArray(new MIMEContent[result.size()]);
372: }
373:
374: public static Part[] getFaultParts(
375: BindingOperation bindingOperation, String faultName)
376: throws Exception {
377: List<Part> result = new ArrayList<Part>();
378:
379: BindingFault bindingFault = bindingOperation
380: .getBindingFault(faultName);
381: SOAPFault soapFault = (SOAPFault) WsdlUtils
382: .getExtensiblityElement(bindingFault
383: .getExtensibilityElements(), SOAPFault.class);
384:
385: Operation operation = bindingOperation.getOperation();
386: if (soapFault != null && soapFault.getName() != null) {
387: Fault fault = operation.getFault(soapFault.getName());
388: if (fault == null)
389: throw new Exception("Missing Fault ["
390: + soapFault.getName() + "] in operation ["
391: + operation.getName() + "]");
392: result.addAll(fault.getMessage().getOrderedParts(null));
393: } else {
394: SOAP12Fault soap12Fault = (SOAP12Fault) WsdlUtils
395: .getExtensiblityElement(bindingFault
396: .getExtensibilityElements(),
397: SOAP12Fault.class);
398:
399: if (soap12Fault != null && soap12Fault.getName() != null) {
400: result.addAll(operation.getFault(soap12Fault.getName())
401: .getMessage().getOrderedParts(null));
402: } else {
403: result.addAll(operation.getFault(faultName)
404: .getMessage().getOrderedParts(null));
405: }
406: }
407:
408: return result.toArray(new Part[result.size()]);
409: }
410:
411: public static Part[] getOutputParts(BindingOperation operation) {
412: BindingOutput bindingOutput = operation.getBindingOutput();
413: if (bindingOutput == null)
414: return new Part[0];
415:
416: List<Part> result = new ArrayList<Part>();
417: Message msg = operation.getOperation().getOutput().getMessage();
418: SOAPBody soapBody = (SOAPBody) WsdlUtils
419: .getExtensiblityElement(bindingOutput
420: .getExtensibilityElements(), SOAPBody.class);
421:
422: if (soapBody == null || soapBody.getParts() == null) {
423: SOAP12Body soap12Body = (SOAP12Body) WsdlUtils
424: .getExtensiblityElement(bindingOutput
425: .getExtensibilityElements(),
426: SOAP12Body.class);
427:
428: if (soap12Body == null || soap12Body.getParts() == null) {
429: result.addAll(msg.getOrderedParts(null));
430: } else {
431: Iterator i = soap12Body.getParts().iterator();
432: while (i.hasNext()) {
433: String partName = (String) i.next();
434: Part part = msg.getPart(partName);
435:
436: result.add(part);
437: }
438: }
439: } else {
440: Iterator i = soapBody.getParts().iterator();
441: while (i.hasNext()) {
442: String partName = (String) i.next();
443: Part part = msg.getPart(partName);
444:
445: result.add(part);
446: }
447: }
448:
449: return result.toArray(new Part[result.size()]);
450: }
451:
452: public static boolean isMultipartRequest(Definition definition,
453: BindingOperation bindingOperation) {
454: return (MIMEMultipartRelated) WsdlUtils.getExtensiblityElement(
455: bindingOperation.getBindingInput()
456: .getExtensibilityElements(),
457: MIMEMultipartRelated.class) != null;
458: }
459:
460: public static String getSoapEndpoint(Port port) {
461: SOAPAddress soapAddress = (SOAPAddress) WsdlUtils
462: .getExtensiblityElement(
463: port.getExtensibilityElements(),
464: SOAPAddress.class);
465: if (soapAddress != null)
466: return soapAddress.getLocationURI();
467:
468: SOAP12Address soap12Address = (SOAP12Address) WsdlUtils
469: .getExtensiblityElement(
470: port.getExtensibilityElements(),
471: SOAP12Address.class);
472: if (soap12Address != null)
473: return soap12Address.getLocationURI();
474:
475: return null;
476: }
477:
478: public static String getSoapBodyNamespace(List list) {
479: SOAPBody soapBody = (SOAPBody) WsdlUtils
480: .getExtensiblityElement(list, SOAPBody.class);
481: if (soapBody != null)
482: return soapBody.getNamespaceURI();
483:
484: SOAP12Body soap12Body = (SOAP12Body) WsdlUtils
485: .getExtensiblityElement(list, SOAP12Body.class);
486: if (soap12Body != null)
487: return soap12Body.getNamespaceURI();
488:
489: return null;
490: }
491:
492: /**
493: * A SOAP-Header wrapper
494: *
495: * @author ole.matzura
496: */
497:
498: public interface SoapHeader {
499: public QName getMessage();
500:
501: public String getPart();
502: }
503:
504: /**
505: * SOAP 1.1 Header implementation
506: *
507: * @author ole.matzura
508: */
509:
510: public static class Soap11Header implements SoapHeader {
511: private final SOAPHeader soapHeader;
512:
513: public Soap11Header(SOAPHeader soapHeader) {
514: this .soapHeader = soapHeader;
515: }
516:
517: public QName getMessage() {
518: return soapHeader.getMessage();
519: }
520:
521: public String getPart() {
522: return soapHeader.getPart();
523: }
524: }
525:
526: /**
527: * SOAP 1.2 Header implementation
528: *
529: * @author ole.matzura
530: */
531:
532: public static class Soap12Header implements SoapHeader {
533: private final SOAP12Header soapHeader;
534:
535: public Soap12Header(SOAP12Header soapHeader) {
536: this .soapHeader = soapHeader;
537: }
538:
539: public QName getMessage() {
540: return soapHeader.getMessage();
541: }
542:
543: public String getPart() {
544: return soapHeader.getPart();
545: }
546: }
547:
548: public static List<SoapHeader> getSoapHeaders(List list) {
549: List<SoapHeader> result = new ArrayList<SoapHeader>();
550:
551: List<SOAPHeader> soapHeaders = WsdlUtils
552: .getExtensiblityElements(list, SOAPHeader.class);
553: if (soapHeaders != null && !soapHeaders.isEmpty()) {
554: for (SOAPHeader header : soapHeaders)
555: result.add(new Soap11Header(header));
556: } else {
557: List<SOAP12Header> soap12Headers = WsdlUtils
558: .getExtensiblityElements(list, SOAP12Header.class);
559: if (soap12Headers != null && !soap12Headers.isEmpty()) {
560: for (SOAP12Header header : soap12Headers)
561: result.add(new Soap12Header(header));
562: }
563: }
564:
565: return result;
566: }
567:
568: public static synchronized Definition readDefinition(String wsdlUrl)
569: throws Exception {
570: if (wsdlReader == null) {
571: WSDLFactory factory = WSDLFactory.newInstance();
572: wsdlReader = factory.newWSDLReader();
573: wsdlReader.setFeature("javax.wsdl.verbose", true);
574: wsdlReader.setFeature("javax.wsdl.importDocuments", true);
575: }
576:
577: return wsdlReader.readWSDL(new UrlWsdlLoader(wsdlUrl));
578: }
579:
580: public static SchemaType getSchemaTypeForPart(
581: WsdlContext wsdlContext, javax.wsdl.Part part)
582: throws Exception {
583: SchemaType schemaType = null;
584: QName elementName = part.getElementName();
585:
586: if (elementName != null) {
587: SchemaGlobalElement elm = wsdlContext.getSchemaTypeLoader()
588: .findElement(elementName);
589: if (elm != null) {
590: schemaType = elm.getType();
591: } else
592: WsdlRequest.log.error("Could not find element ["
593: + elementName + "] specified in part ["
594: + part.getName() + "]");
595: } else {
596: QName typeName = part.getTypeName();
597:
598: if (typeName != null) {
599: schemaType = wsdlContext.getSchemaTypeLoader()
600: .findType(typeName);
601:
602: if (schemaType == null) {
603: WsdlRequest.log.error("Could not find type ["
604: + typeName + "] specified in part ["
605: + part.getName() + "]");
606: }
607: }
608: }
609: return schemaType;
610: }
611: }
|