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;
014:
015: import java.util.ArrayList;
016: import java.util.HashMap;
017: import java.util.List;
018: import java.util.Map;
019:
020: import javax.swing.ImageIcon;
021: import javax.wsdl.Binding;
022: import javax.wsdl.BindingOperation;
023: import javax.wsdl.BindingOutput;
024: import javax.wsdl.Definition;
025: import javax.wsdl.Message;
026: import javax.wsdl.extensions.mime.MIMEContent;
027: import javax.wsdl.extensions.mime.MIMEMultipartRelated;
028: import javax.wsdl.extensions.mime.MIMEPart;
029: import javax.xml.namespace.QName;
030:
031: import org.apache.log4j.Logger;
032: import org.apache.xmlbeans.SchemaType;
033:
034: import com.eviware.soapui.SoapUI;
035: import com.eviware.soapui.config.CallConfig;
036: import com.eviware.soapui.config.OperationConfig;
037: import com.eviware.soapui.config.PartsConfig.Part;
038: import com.eviware.soapui.impl.wsdl.support.soap.SoapMessageBuilder;
039: import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlContext;
040: import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils;
041: import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils.SoapHeader;
042: import com.eviware.soapui.model.iface.MessagePart;
043: import com.eviware.soapui.model.iface.Operation;
044: import com.eviware.soapui.model.iface.Request;
045: import com.eviware.soapui.model.iface.MessagePart.FaultPart;
046: import com.eviware.soapui.support.UISupport;
047:
048: /**
049: * WSDL implementation of Operation, maps to a WSDL BindingOperation
050: *
051: * @author Ole.Matzura
052: */
053:
054: public class WsdlOperation extends
055: AbstractWsdlModelItem<OperationConfig> implements Operation {
056: public static final String STYLE_DOCUMENT = "Document";
057: public static final String STYLE_RPC = "RPC";
058:
059: public final static Logger log = Logger
060: .getLogger(WsdlOperation.class);
061: private List<WsdlRequest> requests = new ArrayList<WsdlRequest>();
062: private WsdlInterface iface;
063: private ImageIcon oneWayIcon;
064:
065: public WsdlOperation(WsdlInterface iface,
066: OperationConfig operationConfig) {
067: super (operationConfig, iface, "/operation.gif");
068: this .iface = iface;
069:
070: if (operationConfig.isSetIsOneWay()) {
071: operationConfig.setIsOneWay(false);
072: }
073:
074: List<CallConfig> requestConfigs = getConfig().getCallList();
075: for (CallConfig config : requestConfigs) {
076: requests.add(new WsdlRequest(this , config));
077: }
078:
079: oneWayIcon = UISupport.createImageIcon("/onewayoperation.gif");
080: }
081:
082: public String getAction() {
083: return getConfig().getAction();
084: }
085:
086: public WsdlRequest getRequestAt(int index) {
087: return requests.get(index);
088: }
089:
090: public WsdlRequest getRequestByName(String requestName) {
091: return (WsdlRequest) getWsdlModelItemByName(requests,
092: requestName);
093: }
094:
095: public int getRequestCount() {
096: return requests.size();
097: }
098:
099: public ImageIcon getIcon() {
100: if (isOneWay())
101: return oneWayIcon;
102: else
103: return super .getIcon();
104: }
105:
106: public WsdlRequest addNewRequest(String name) {
107: WsdlRequest requestImpl = new WsdlRequest(this , getConfig()
108: .addNewCall());
109: requestImpl.setName(name);
110: requests.add(requestImpl);
111: ((WsdlInterface) getInterface()).fireRequestAdded(requestImpl);
112: return requestImpl;
113: }
114:
115: public WsdlInterface getInterface() {
116: return iface;
117: }
118:
119: public void setAction(String soapAction) {
120: String old = getAction();
121: getConfig().setAction(soapAction);
122: notifyPropertyChanged(ACTION_PROPERTY, old, soapAction);
123: }
124:
125: public String createRequest(boolean buildOptional) {
126: if (iface.getBindingName() == null) {
127: UISupport
128: .showErrorMessage("Missing binding name, please try to refresh "
129: + "Interface\nfor request generation to work correctly");
130: return null;
131: }
132:
133: if (getBindingOperationName() == null) {
134: UISupport
135: .showErrorMessage("Missing bindingOperation name, please try to refresh "
136: + "Interface\nfor request generation to work correctly");
137: return null;
138: }
139:
140: try {
141: SoapMessageBuilder builder = (SoapMessageBuilder) iface
142: .getMessageBuilder();
143: BindingOperation bindingOperation = findBindingOperation(iface
144: .getWsdlContext().getDefinition());
145:
146: if (bindingOperation == null) {
147: UISupport
148: .showErrorMessage("Failed to find bindingOperation, please try to refresh "
149: + "Interface\nfor request generation to work correctly");
150: return null;
151: }
152:
153: return builder.buildSoapRequest(bindingOperation,
154: buildOptional);
155: } catch (Exception e) {
156: SoapUI.logError(e);
157: return null;
158: }
159: }
160:
161: public String createResponse(boolean buildOptional) {
162: if (iface.getBindingName() == null) {
163: UISupport
164: .showErrorMessage("Missing binding name, please try to refresh "
165: + "Interface\nfor request generation to work correctly");
166: return null;
167: }
168:
169: if (getBindingOperationName() == null) {
170: UISupport
171: .showErrorMessage("Missing bindingOperation name, please try to refresh "
172: + "Interface\nfor request generation to work correctly");
173: return null;
174: }
175:
176: try {
177: SoapMessageBuilder builder = (SoapMessageBuilder) iface
178: .getMessageBuilder();
179: BindingOperation bindingOperation = findBindingOperation(iface
180: .getWsdlContext().getDefinition());
181:
182: if (bindingOperation == null) {
183: UISupport
184: .showErrorMessage("Failed to find bindingOperation, please try to refresh "
185: + "Interface\nfor request generation to work correctly");
186: return null;
187: }
188:
189: return builder.buildSoapResponse(bindingOperation,
190: buildOptional);
191: } catch (Exception e) {
192: SoapUI.logError(e);
193: return null;
194: }
195: }
196:
197: public BindingOperation findBindingOperation(Definition definition) {
198: Binding binding = definition.getBinding(iface.getBindingName());
199: if (binding == null)
200: return null;
201:
202: String inputName = getInputName();
203: String outputName = getOutputName();
204:
205: if (inputName == null)
206: inputName = ":none";
207:
208: if (outputName == null)
209: outputName = ":none";
210:
211: BindingOperation result = binding.getBindingOperation(
212: getConfig().getBindingOperationName(), inputName,
213: outputName);
214:
215: if (result == null
216: && (inputName.equals(":none") || outputName
217: .equals(":none"))) {
218: // fall back to this behaviour for WSDL4j 1.5.0 compatibility
219: result = binding.getBindingOperation(getConfig()
220: .getBindingOperationName(), inputName
221: .equals(":none") ? null : inputName, outputName
222: .equals(":none") ? null : outputName);
223: }
224: return result;
225: }
226:
227: public void removeRequest(WsdlRequest request) {
228: int ix = requests.indexOf(request);
229: requests.remove(ix);
230:
231: try {
232: ((WsdlInterface) getInterface())
233: .fireRequestRemoved(request);
234: } finally {
235: request.release();
236: getConfig().removeCall(ix);
237: }
238: }
239:
240: public String getBindingOperationName() {
241: return getConfig().getBindingOperationName();
242: }
243:
244: public void setBindingOperationName(String name) {
245: getConfig().setBindingOperationName(name);
246: }
247:
248: public void setInputName(String name) {
249: getConfig().setInputName(name);
250: }
251:
252: public String getInputName() {
253: String inputName = getConfig().getInputName();
254: return inputName == null || inputName.trim().length() == 0 ? null
255: : inputName;
256: }
257:
258: public void setOutputName(String name) {
259: if (name == null) {
260: if (getConfig().isSetOutputName())
261: getConfig().unsetOutputName();
262: } else
263: getConfig().setOutputName(name);
264: }
265:
266: public String getOutputName() {
267: String outputName = getConfig().getOutputName();
268: return outputName == null || outputName.trim().length() == 0 ? null
269: : outputName;
270: }
271:
272: public void setOneWay(boolean isOneWay) {
273: getConfig().setIsOneWay(isOneWay);
274: }
275:
276: public boolean isOneWay() {
277: return getConfig().getIsOneWay();
278: }
279:
280: public void initFromBindingOperation(BindingOperation operation,
281: boolean notifyUpdate) {
282: setAction(WsdlUtils.getSoapAction(operation));
283: setName(operation.getOperation().getName());
284: setBindingOperationName(operation.getName());
285: setInputName(operation.getBindingInput().getName());
286:
287: BindingOutput bindingOutput = operation.getBindingOutput();
288:
289: // bindingOutput is null for oneway operations
290: if (bindingOutput != null)
291: setOutputName(bindingOutput.getName());
292: else
293: setOutputName(null);
294:
295: setOneWay(bindingOutput == null);
296:
297: initAttachments(operation);
298:
299: if (notifyUpdate) {
300: iface.fireOperationUpdated(this );
301: }
302: }
303:
304: @SuppressWarnings("unchecked")
305: private void initAttachments(BindingOperation operation) {
306: if (getConfig().isSetRequestParts())
307: getConfig().unsetRequestParts();
308:
309: if (getConfig().isSetResponseParts())
310: getConfig().unsetResponseParts();
311:
312: BindingOutput bindingOutput = operation.getBindingOutput();
313:
314: if (bindingOutput != null) {
315: MIMEMultipartRelated multipartOutput = (MIMEMultipartRelated) WsdlUtils
316: .getExtensiblityElement(bindingOutput
317: .getExtensibilityElements(),
318: MIMEMultipartRelated.class);
319:
320: getConfig().setReceivesAttachments(multipartOutput != null);
321: if (multipartOutput != null) {
322: List<MIMEPart> parts = multipartOutput.getMIMEParts();
323: Map<String, Part> partMap = new HashMap<String, Part>();
324:
325: for (int c = 0; c < parts.size(); c++) {
326: List<MIMEContent> contentParts = WsdlUtils
327: .getExtensiblityElements(parts.get(c)
328: .getExtensibilityElements(),
329: MIMEContent.class);
330:
331: for (MIMEContent content : contentParts) {
332: Part part = partMap.get(content.getPart());
333: if (part != null) {
334: if (!part.getContentTypeList().contains(
335: content.getType()))
336: part.addContentType(content.getType());
337: } else {
338: if (!getConfig().isSetResponseParts())
339: getConfig().addNewResponseParts();
340:
341: Part responsePart = getConfig()
342: .getResponseParts().addNewPart();
343: responsePart.addContentType(content
344: .getType());
345: responsePart.setName(content.getPart());
346:
347: partMap.put(responsePart.getName(),
348: responsePart);
349: }
350: }
351: }
352: }
353: }
354:
355: MIMEMultipartRelated multipartInput = (MIMEMultipartRelated) WsdlUtils
356: .getExtensiblityElement(operation.getBindingInput()
357: .getExtensibilityElements(),
358: MIMEMultipartRelated.class);
359:
360: getConfig().setSendsAttachments(multipartInput != null);
361: if (multipartInput != null) {
362: List<MIMEPart> parts = multipartInput.getMIMEParts();
363: Map<String, Part> partMap = new HashMap<String, Part>();
364:
365: for (int c = 0; c < parts.size(); c++) {
366: List<MIMEContent> contentParts = WsdlUtils
367: .getExtensiblityElements(parts.get(c)
368: .getExtensibilityElements(),
369: MIMEContent.class);
370:
371: for (MIMEContent content : contentParts) {
372: Part part = partMap.get(content.getPart());
373: if (part != null) {
374: if (!part.getContentTypeList().contains(
375: content.getType()))
376: part.addContentType(content.getType());
377: } else {
378: if (!getConfig().isSetRequestParts())
379: getConfig().addNewRequestParts();
380:
381: Part requestPart = getConfig()
382: .getRequestParts().addNewPart();
383: requestPart.addContentType(content.getType());
384: requestPart.setName(content.getPart());
385:
386: partMap.put(requestPart.getName(), requestPart);
387: }
388: }
389: }
390: }
391: }
392:
393: public boolean getReceivesAttachments() {
394: return getConfig().getReceivesAttachments();
395: }
396:
397: public boolean getSendsAttachments() {
398: return getConfig().getSendsAttachments();
399: }
400:
401: @SuppressWarnings("unchecked")
402: public QName getRequestBodyElementQName() throws Exception {
403: WsdlInterface iface = (WsdlInterface) getInterface();
404:
405: Definition definition = iface.getWsdlContext().getDefinition();
406: BindingOperation bindingOperation = findBindingOperation(definition);
407: if (WsdlUtils.isRpc(definition, bindingOperation)) {
408: String ns = WsdlUtils.getSoapBodyNamespace(bindingOperation
409: .getBindingInput().getExtensibilityElements());
410: if (ns == null) {
411: ns = definition.getTargetNamespace();
412: }
413:
414: return new QName(ns, bindingOperation.getName());
415: } else {
416: List<javax.wsdl.Part> parts = bindingOperation
417: .getOperation().getInput().getMessage()
418: .getOrderedParts(null);
419: if (parts == null || parts.isEmpty())
420: return null;
421:
422: javax.wsdl.Part part = parts.get(0);
423:
424: if (part.getElementName() != null) {
425: return part.getElementName();
426: } else {
427: return new QName(definition.getTargetNamespace(), part
428: .getName());
429: }
430: }
431: }
432:
433: @SuppressWarnings("unchecked")
434: public QName getResponseBodyElementQName() throws Exception {
435: if (isOneWay())
436: return null;
437:
438: WsdlInterface iface = (WsdlInterface) getInterface();
439:
440: Definition definition = iface.getWsdlContext().getDefinition();
441: BindingOperation bindingOperation = findBindingOperation(definition);
442: if (WsdlUtils.isRpc(definition, bindingOperation)) {
443: String ns = WsdlUtils.getSoapBodyNamespace(bindingOperation
444: .getBindingOutput().getExtensibilityElements());
445: if (ns == null) {
446: ns = definition.getTargetNamespace();
447: }
448:
449: return new QName(ns, bindingOperation.getName()
450: + "Response");
451: } else {
452: List<javax.wsdl.Part> parts = bindingOperation
453: .getOperation().getOutput().getMessage()
454: .getOrderedParts(null);
455: if (parts == null || parts.isEmpty())
456: return null;
457:
458: javax.wsdl.Part part = parts.get(0);
459:
460: if (part.getElementName() != null) {
461: return part.getElementName();
462: } else {
463: return new QName(definition.getTargetNamespace(), part
464: .getName());
465: }
466: }
467: }
468:
469: public String getStyle() {
470: WsdlContext wsdlContext = iface.getWsdlContext();
471: if (!wsdlContext.isLoaded())
472: return "<not loaded>";
473:
474: try {
475: Definition definition = wsdlContext.getDefinition();
476: BindingOperation bindingOperation = findBindingOperation(definition);
477:
478: if (bindingOperation == null)
479: return "<missing bindingOperation>";
480:
481: if (WsdlUtils.isRpc(definition, bindingOperation)) {
482: return WsdlOperation.STYLE_RPC;
483: } else {
484: return WsdlOperation.STYLE_DOCUMENT;
485: }
486: } catch (Exception e) {
487: SoapUI.logError(e);
488: return "<error>";
489: }
490: }
491:
492: public void release() {
493: super .release();
494:
495: for (WsdlRequest request : requests)
496: request.release();
497: }
498:
499: public BindingOperation getBindingOperation() {
500: try {
501: return findBindingOperation(((WsdlInterface) getInterface())
502: .getWsdlContext().getDefinition());
503: } catch (Exception e) {
504: SoapUI.logError(e);
505: return null;
506: }
507: }
508:
509: public List<Request> getRequests() {
510: return new ArrayList<Request>(requests);
511: }
512:
513: public MessagePart[] getDefaultRequestParts() {
514: try {
515: // init
516: List<MessagePart> result = new ArrayList<MessagePart>();
517: WsdlContext wsdlContext = getInterface().getWsdlContext();
518: BindingOperation bindingOperation = findBindingOperation(wsdlContext
519: .getDefinition());
520:
521: if (bindingOperation == null)
522: return new MessagePart[0];
523:
524: // header parts
525: List<SoapHeader> headers = WsdlUtils
526: .getSoapHeaders(bindingOperation.getBindingInput()
527: .getExtensibilityElements());
528:
529: for (int i = 0; i < headers.size(); i++) {
530: SoapHeader header = headers.get(i);
531:
532: Message message = wsdlContext.getDefinition()
533: .getMessage(header.getMessage());
534: if (message == null) {
535: log.error("Missing message for header: "
536: + header.getMessage());
537: continue;
538: }
539:
540: javax.wsdl.Part part = message
541: .getPart(header.getPart());
542:
543: if (part != null) {
544: SchemaType schemaType = WsdlUtils
545: .getSchemaTypeForPart(wsdlContext, part);
546: if (schemaType != null)
547: result.add(new WsdlHeaderPart(part.getName(),
548: schemaType, part.getElementName()));
549: } else
550: log.error("Missing part for header; "
551: + header.getPart());
552: }
553:
554: // content parts
555: javax.wsdl.Part[] parts = WsdlUtils
556: .getInputParts(bindingOperation);
557:
558: for (int i = 0; i < parts.length; i++) {
559: javax.wsdl.Part part = parts[i];
560:
561: if (!WsdlUtils.isAttachmentInputPart(part,
562: bindingOperation)) {
563: SchemaType schemaType = WsdlUtils
564: .getSchemaTypeForPart(wsdlContext, part);
565: if (schemaType != null)
566: result.add(new WsdlContentPart(part.getName(),
567: schemaType, part.getElementName()));
568: }
569: }
570:
571: return result.toArray(new MessagePart[result.size()]);
572: } catch (Exception e) {
573: SoapUI.logError(e);
574: return new MessagePart[0];
575: }
576: }
577:
578: public MessagePart[] getDefaultResponseParts() {
579: try {
580: // init
581: List<MessagePart> result = new ArrayList<MessagePart>();
582: WsdlContext wsdlContext = getInterface().getWsdlContext();
583: BindingOperation bindingOperation = findBindingOperation(wsdlContext
584: .getDefinition());
585:
586: if (bindingOperation == null)
587: return new MessagePart[0];
588:
589: // header parts
590: List<SoapHeader> headers = WsdlUtils
591: .getSoapHeaders(bindingOperation.getBindingOutput()
592: .getExtensibilityElements());
593:
594: for (int i = 0; i < headers.size(); i++) {
595: SoapHeader header = headers.get(i);
596:
597: Message message = wsdlContext.getDefinition()
598: .getMessage(header.getMessage());
599: if (message == null) {
600: log.error("Missing message for header: "
601: + header.getMessage());
602: continue;
603: }
604:
605: javax.wsdl.Part part = message
606: .getPart(header.getPart());
607:
608: if (part != null) {
609: SchemaType schemaType = WsdlUtils
610: .getSchemaTypeForPart(wsdlContext, part);
611: if (schemaType != null)
612: result.add(new WsdlHeaderPart(part.getName(),
613: schemaType, part.getElementName()));
614: } else
615: log.error("Missing part for header; "
616: + header.getPart());
617: }
618:
619: // content parts
620: javax.wsdl.Part[] parts = WsdlUtils
621: .getOutputParts(bindingOperation);
622:
623: for (int i = 0; i < parts.length; i++) {
624: javax.wsdl.Part part = parts[i];
625:
626: if (!WsdlUtils.isAttachmentOutputPart(part,
627: bindingOperation)) {
628: SchemaType schemaType = WsdlUtils
629: .getSchemaTypeForPart(wsdlContext, part);
630: if (schemaType != null)
631: result.add(new WsdlContentPart(part.getName(),
632: schemaType, part.getElementName()));
633: }
634: }
635:
636: return result.toArray(new MessagePart[result.size()]);
637: } catch (Exception e) {
638: SoapUI.logError(e);
639: return new MessagePart[0];
640: }
641: }
642:
643: public MessagePart[] getFaultParts() {
644: BindingOperation bindingOperation = getBindingOperation();
645: Map bindingFaults = bindingOperation.getBindingFaults();
646:
647: List<MessagePart> result = new ArrayList<MessagePart>();
648: for (Object key : bindingFaults.keySet()) {
649: result.add(new WsdlFaultPart((String) key));
650: }
651:
652: return result.toArray(new MessagePart[result.size()]);
653: }
654:
655: private class WsdlFaultPart extends FaultPart {
656: private final String name;
657:
658: public WsdlFaultPart(String name) {
659: this .name = name;
660: }
661:
662: @Override
663: public javax.wsdl.Part[] getWsdlParts() {
664: try {
665: return WsdlUtils.getFaultParts(getBindingOperation(),
666: name);
667: } catch (Exception e) {
668: log.error(e.toString(), e);
669: }
670:
671: return new javax.wsdl.Part[0];
672: }
673:
674: @Override
675: public QName getPartElement() {
676: return null;
677: }
678:
679: public String getDescription() {
680: return null;
681: }
682:
683: public String getName() {
684: return name;
685: }
686:
687: @Override
688: public SchemaType getSchemaType() {
689: return null;
690: }
691: }
692:
693: @Override
694: public void onSave() {
695: for (WsdlRequest request : requests)
696: request.onSave();
697: }
698: }
|