1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl;
14
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.List;
18 import java.util.Map;
19
20 import javax.swing.ImageIcon;
21 import javax.wsdl.BindingOperation;
22 import javax.wsdl.BindingOutput;
23 import javax.wsdl.Definition;
24 import javax.wsdl.Message;
25 import javax.wsdl.extensions.mime.MIMEContent;
26 import javax.wsdl.extensions.mime.MIMEMultipartRelated;
27 import javax.wsdl.extensions.mime.MIMEPart;
28 import javax.xml.namespace.QName;
29
30 import org.apache.log4j.Logger;
31 import org.apache.xmlbeans.SchemaGlobalElement;
32 import org.apache.xmlbeans.SchemaType;
33
34 import com.eviware.soapui.SoapUI;
35 import com.eviware.soapui.config.CallConfig;
36 import com.eviware.soapui.config.OperationConfig;
37 import com.eviware.soapui.config.PartsConfig.Part;
38 import com.eviware.soapui.impl.wsdl.support.soap.SoapMessageBuilder;
39 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlContext;
40 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils;
41 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils.SoapHeader;
42 import com.eviware.soapui.model.ModelItem;
43 import com.eviware.soapui.model.iface.MessagePart;
44 import com.eviware.soapui.model.iface.Operation;
45 import com.eviware.soapui.model.iface.Request;
46 import com.eviware.soapui.model.iface.MessagePart.FaultPart;
47 import com.eviware.soapui.support.UISupport;
48
49 /***
50 * WSDL implementation of Operation, maps to a WSDL BindingOperation
51 *
52 * @author Ole.Matzura
53 */
54
55 public class WsdlOperation extends AbstractWsdlModelItem<OperationConfig> implements Operation
56 {
57 public static final String STYLE_DOCUMENT = "Document";
58 public static final String STYLE_RPC = "RPC";
59
60 public final static Logger log = Logger.getLogger( WsdlOperation.class );
61 private List<WsdlRequest> requests = new ArrayList<WsdlRequest>();
62 private WsdlInterface iface;
63 private ImageIcon oneWayIcon;
64
65 public WsdlOperation( WsdlInterface iface, OperationConfig operationConfig )
66 {
67 super( operationConfig, iface, "/operation.gif" );
68 this.iface = iface;
69
70 if( !operationConfig.isSetIsOneWay())
71 {
72 operationConfig.setIsOneWay( false );
73 }
74
75 List<CallConfig> requestConfigs = getConfig().getCallList();
76 for (CallConfig config : requestConfigs)
77 {
78 requests.add( new WsdlRequest( this, config));
79 }
80
81 oneWayIcon = UISupport.createImageIcon( "/onewayoperation.gif" );
82 }
83
84 public String getAction()
85 {
86 String action = getConfig().getAction();
87 return action == null ? "" : action;
88 }
89
90 public WsdlRequest getRequestAt(int index)
91 {
92 return requests.get( index );
93 }
94
95 public WsdlRequest getRequestByName(String requestName)
96 {
97 return (WsdlRequest) getWsdlModelItemByName( requests, requestName );
98 }
99
100 public int getRequestCount()
101 {
102 return requests.size();
103 }
104
105 @Override
106 public ImageIcon getIcon()
107 {
108 if( isOneWay() )
109 return oneWayIcon;
110 else
111 return super.getIcon();
112 }
113
114 public WsdlRequest addNewRequest( String name )
115 {
116 WsdlRequest requestImpl = new WsdlRequest( this, getConfig().addNewCall() );
117 requestImpl.setName( name );
118 requests.add( requestImpl );
119 (getInterface()).fireRequestAdded( requestImpl );
120 return requestImpl;
121 }
122
123 public WsdlInterface getInterface()
124 {
125 return iface;
126 }
127
128 public void setAction(String soapAction)
129 {
130 String old = getAction();
131 getConfig().setAction( soapAction );
132 notifyPropertyChanged( ACTION_PROPERTY, old, soapAction );
133 }
134
135 public String createRequest( boolean buildOptional )
136 {
137 if( iface.getBindingName() == null )
138 {
139 UISupport.showErrorMessage( "Missing binding name, please try to refresh " +
140 "Interface\nfor request generation to work correctly" );
141 return null;
142 }
143
144 if( getBindingOperationName() == null )
145 {
146 UISupport.showErrorMessage( "Missing bindingOperation name, please try to refresh " +
147 "Interface\nfor request generation to work correctly" );
148 return null;
149 }
150
151 try
152 {
153 SoapMessageBuilder builder = iface.getMessageBuilder();
154 BindingOperation bindingOperation = findBindingOperation( iface.getWsdlContext().getDefinition() );
155
156 if( bindingOperation == null )
157 {
158 UISupport.showErrorMessage( "Failed to find bindingOperation, please try to refresh " +
159 "Interface\nfor request generation to work correctly" );
160 return null;
161 }
162
163 return builder.buildSoapRequest( bindingOperation, buildOptional );
164 }
165 catch (Exception e)
166 {
167 SoapUI.logError( e );
168 return null;
169 }
170 }
171
172 public String createResponse( boolean buildOptional )
173 {
174 if( isOneWay() )
175 {
176 return null;
177 }
178
179 if( iface.getBindingName() == null )
180 {
181 UISupport.showErrorMessage( "Missing binding name, please try to refresh " +
182 "Interface\nfor request generation to work correctly" );
183 return null;
184 }
185
186 if( getBindingOperationName() == null )
187 {
188 UISupport.showErrorMessage( "Missing bindingOperation name, please try to refresh " +
189 "Interface\nfor request generation to work correctly" );
190 return null;
191 }
192
193 try
194 {
195 SoapMessageBuilder builder = iface.getMessageBuilder();
196 BindingOperation bindingOperation = findBindingOperation( iface.getWsdlContext().getDefinition() );
197
198 if( bindingOperation == null )
199 {
200 UISupport.showErrorMessage( "Failed to find bindingOperation, please try to refresh " +
201 "Interface\nfor request generation to work correctly" );
202 return null;
203 }
204
205 return builder.buildSoapResponse( bindingOperation, buildOptional );
206 }
207 catch (Exception e)
208 {
209 SoapUI.logError( e );
210 return null;
211 }
212 }
213
214 public BindingOperation findBindingOperation(Definition definition)
215 {
216 String bindingOperationName = getConfig().getBindingOperationName();
217 return iface.findBindingOperation( definition, bindingOperationName, getInputName(), getOutputName());
218 }
219
220 public void removeRequest( WsdlRequest request )
221 {
222 int ix = requests.indexOf( request );
223 requests.remove( ix );
224
225 try
226 {
227 (getInterface()).fireRequestRemoved( request );
228 }
229 finally
230 {
231 request.release();
232 getConfig().removeCall( ix );
233 }
234 }
235
236 public String getBindingOperationName()
237 {
238 return getConfig().getBindingOperationName();
239 }
240
241 public void setBindingOperationName( String name )
242 {
243 getConfig().setBindingOperationName( name );
244 }
245
246 public void setInputName( String name )
247 {
248 getConfig().setInputName( name );
249 }
250
251 public String getInputName()
252 {
253 String inputName = getConfig().getInputName();
254 return inputName == null || inputName.trim().length() == 0 ? null : inputName;
255 }
256
257 public void setOutputName( String name )
258 {
259 if( name == null )
260 {
261 if( getConfig().isSetOutputName() )
262 getConfig().unsetOutputName();
263 }
264 else
265 getConfig().setOutputName( name );
266 }
267
268 public String getOutputName()
269 {
270 String outputName = getConfig().getOutputName();
271 return outputName == null || outputName.trim().length() == 0 ? null : outputName;
272 }
273
274 public void setOneWay( boolean isOneWay )
275 {
276 getConfig().setIsOneWay( isOneWay );
277 }
278
279 public boolean isOneWay()
280 {
281 return getConfig().getIsOneWay();
282 }
283
284 public void initFromBindingOperation(BindingOperation operation )
285 {
286 setAction( WsdlUtils.getSoapAction( operation ));
287 setName( operation.getOperation().getName() );
288 setBindingOperationName( operation.getName() );
289 setInputName( operation.getBindingInput().getName() );
290
291 BindingOutput bindingOutput = operation.getBindingOutput();
292
293
294 if( bindingOutput != null )
295 setOutputName( bindingOutput.getName() );
296 else
297 setOutputName( null );
298
299 setOneWay( bindingOutput == null );
300
301 initAttachments(operation);
302 }
303
304 @SuppressWarnings("unchecked")
305 private void initAttachments(BindingOperation operation)
306 {
307 if( getConfig().isSetRequestParts() )
308 getConfig().unsetRequestParts();
309
310 if( getConfig().isSetResponseParts() )
311 getConfig().unsetResponseParts();
312
313 BindingOutput bindingOutput = operation.getBindingOutput();
314
315 if( bindingOutput != null )
316 {
317 MIMEMultipartRelated multipartOutput = WsdlUtils.getExtensiblityElement(
318 bindingOutput.getExtensibilityElements(), MIMEMultipartRelated.class );
319
320 getConfig().setReceivesAttachments( multipartOutput != null );
321 if( multipartOutput != null )
322 {
323 List<MIMEPart> parts = multipartOutput.getMIMEParts();
324 Map<String,Part> partMap = new HashMap<String,Part>();
325
326 for( int c = 0; c < parts.size(); c++ )
327 {
328 List<MIMEContent> contentParts = WsdlUtils.getExtensiblityElements( parts.get(c).getExtensibilityElements(), MIMEContent.class );
329
330 for( MIMEContent content : contentParts )
331 {
332 Part part = partMap.get( content.getPart());
333 if( part != null )
334 {
335 if( !part.getContentTypeList().contains( content.getType() ))
336 part.addContentType( content.getType() );
337 }
338 else
339 {
340 if( !getConfig().isSetResponseParts() )
341 getConfig().addNewResponseParts();
342
343 Part responsePart = getConfig().getResponseParts().addNewPart();
344 responsePart.addContentType( content.getType() );
345 responsePart.setName( content.getPart() );
346
347 partMap.put( responsePart.getName(), responsePart );
348 }
349 }
350 }
351 }
352 }
353
354 MIMEMultipartRelated multipartInput = WsdlUtils.getExtensiblityElement(
355 operation.getBindingInput().getExtensibilityElements(), MIMEMultipartRelated.class );
356
357 getConfig().setSendsAttachments( multipartInput != null );
358 if( multipartInput != null )
359 {
360 List<MIMEPart> parts = multipartInput.getMIMEParts();
361 Map<String,Part> partMap = new HashMap<String,Part>();
362
363 for( int c = 0; c < parts.size(); c++ )
364 {
365 List<MIMEContent> contentParts = WsdlUtils.getExtensiblityElements( parts.get(c).getExtensibilityElements(), MIMEContent.class );
366
367 for( MIMEContent content : contentParts )
368 {
369 Part part = partMap.get( content.getPart());
370 if( part != null )
371 {
372 if( !part.getContentTypeList().contains( content.getType() ))
373 part.addContentType( content.getType() );
374 }
375 else
376 {
377 if( !getConfig().isSetRequestParts() )
378 getConfig().addNewRequestParts();
379
380 Part requestPart = getConfig().getRequestParts().addNewPart();
381 requestPart.addContentType( content.getType() );
382 requestPart.setName( content.getPart() );
383
384 partMap.put( requestPart.getName(), requestPart );
385 }
386 }
387 }
388 }
389 }
390
391 public boolean getReceivesAttachments()
392 {
393 return getConfig().getReceivesAttachments();
394 }
395
396 public boolean getSendsAttachments()
397 {
398 return getConfig().getSendsAttachments();
399 }
400
401 @SuppressWarnings("unchecked")
402 public QName getRequestBodyElementQName() throws Exception
403 {
404 WsdlInterface iface = getInterface();
405
406 Definition definition = iface.getWsdlContext().getDefinition();
407 BindingOperation bindingOperation = findBindingOperation( definition );
408 if( WsdlUtils.isRpc( definition, bindingOperation))
409 {
410 String ns = WsdlUtils.getSoapBodyNamespace( bindingOperation.getBindingInput().getExtensibilityElements() );
411 if( ns == null )
412 {
413 ns = definition.getTargetNamespace();
414 }
415
416 return new QName( ns, bindingOperation.getName() );
417 }
418 else
419 {
420 Message message = bindingOperation.getOperation().getInput().getMessage();
421 List<javax.wsdl.Part> parts = message.getOrderedParts( null );
422 if( parts == null || parts.isEmpty() )
423 return null;
424
425 int ix = 0;
426 javax.wsdl.Part part = parts.get( 0 );
427
428 while( part != null && (WsdlUtils.isAttachmentInputPart( part, bindingOperation ) || WsdlUtils.isHeaderInputPart( part, message, bindingOperation )) )
429 {
430 ix++;
431 if( ix < parts.size() )
432 part = parts.get( ix );
433 else
434 part = null;
435 }
436
437 if( part == null )
438 return null;
439
440 if( part.getElementName() != null )
441 {
442 return part.getElementName();
443 }
444 else
445 {
446 return new QName( definition.getTargetNamespace(), part.getName() );
447 }
448 }
449 }
450
451 @SuppressWarnings("unchecked")
452 public QName getResponseBodyElementQName() throws Exception
453 {
454 if( isOneWay() )
455 return null;
456
457 WsdlInterface iface = getInterface();
458
459 Definition definition = iface.getWsdlContext().getDefinition();
460 BindingOperation bindingOperation = findBindingOperation( definition );
461 if( WsdlUtils.isRpc( definition, bindingOperation))
462 {
463 String ns = WsdlUtils.getSoapBodyNamespace( bindingOperation.getBindingOutput().getExtensibilityElements() );
464 if( ns == null )
465 {
466 ns = definition.getTargetNamespace();
467 }
468
469 return new QName( ns, bindingOperation.getName() + "Response" );
470 }
471 else
472 {
473 Message message = bindingOperation.getOperation().getOutput().getMessage();
474 List<javax.wsdl.Part> parts = message.getOrderedParts( null );
475 if( parts == null || parts.isEmpty() )
476 return null;
477
478 int ix = 0;
479 javax.wsdl.Part part = parts.get( 0 );
480
481 while( part != null && (WsdlUtils.isAttachmentOutputPart( part, bindingOperation ) || WsdlUtils.isHeaderOutputPart( part, message, bindingOperation )) )
482 {
483 ix++;
484 if( ix < parts.size() )
485 part = parts.get( ix );
486 else
487 part = null;
488 }
489
490 if( part == null )
491 return null;
492
493 if( part.getElementName() != null )
494 {
495 return part.getElementName();
496 }
497 else
498 {
499 return new QName( definition.getTargetNamespace(), part.getName() );
500 }
501 }
502 }
503
504 public String getStyle()
505 {
506 WsdlContext wsdlContext = iface.getWsdlContext();
507 if( !wsdlContext.isLoaded() )
508 return "<not loaded>";
509
510 try
511 {
512 Definition definition = wsdlContext.getDefinition();
513 BindingOperation bindingOperation = findBindingOperation( definition);
514
515 if( bindingOperation == null )
516 return "<missing bindingOperation>";
517
518 if( WsdlUtils.isRpc( definition, bindingOperation ))
519 {
520 return WsdlOperation.STYLE_RPC;
521 }
522 else
523 {
524 return WsdlOperation.STYLE_DOCUMENT;
525 }
526 }
527 catch (Exception e)
528 {
529 SoapUI.logError( e );
530 return "<error>";
531 }
532 }
533
534 @Override
535 public void release()
536 {
537 super.release();
538
539 for( WsdlRequest request : requests )
540 request.release();
541 }
542
543 public BindingOperation getBindingOperation()
544 {
545 try
546 {
547 return findBindingOperation( getInterface().getWsdlContext().getDefinition() );
548 }
549 catch( Exception e )
550 {
551 SoapUI.logError( e );
552 return null;
553 }
554 }
555
556 public List<Request> getRequests()
557 {
558 return new ArrayList<Request>( requests );
559 }
560
561 public MessagePart[] getDefaultRequestParts()
562 {
563 try
564 {
565
566 List<MessagePart> result = new ArrayList<MessagePart>();
567 WsdlContext wsdlContext = getInterface().getWsdlContext();
568 BindingOperation bindingOperation = findBindingOperation(wsdlContext.getDefinition());
569
570 if( bindingOperation == null )
571 return new MessagePart[0];
572
573
574 List<SoapHeader> headers = WsdlUtils.getSoapHeaders( bindingOperation.getBindingInput()
575 .getExtensibilityElements());
576
577 for (int i = 0; i < headers.size(); i++)
578 {
579 SoapHeader header = headers.get( i );
580
581 Message message = wsdlContext.getDefinition().getMessage( header.getMessage() );
582 if( message == null )
583 {
584 log.error( "Missing message for header: " + header.getMessage() );
585 continue;
586 }
587
588 javax.wsdl.Part part = message.getPart( header.getPart() );
589
590 if( part != null )
591 {
592 SchemaType schemaType = WsdlUtils.getSchemaTypeForPart( wsdlContext, part );
593 SchemaGlobalElement schemaElement = WsdlUtils.getSchemaElementForPart( wsdlContext, part );
594 if( schemaType != null )
595 result.add( new WsdlHeaderPart( part.getName(), schemaType, part.getElementName(), schemaElement ));
596 }
597 else
598 log.error( "Missing part for header; " + header.getPart() );
599 }
600
601
602 javax.wsdl.Part[] parts = WsdlUtils.getInputParts( bindingOperation );
603
604 for( int i = 0; i < parts.length; i++ )
605 {
606 javax.wsdl.Part part = parts[i];
607
608 if( !WsdlUtils.isAttachmentInputPart( part, bindingOperation ))
609 {
610 SchemaType schemaType = WsdlUtils.getSchemaTypeForPart( wsdlContext, part );
611 SchemaGlobalElement schemaElement = WsdlUtils.getSchemaElementForPart( wsdlContext, part );
612 if( schemaType != null )
613 result.add( new WsdlContentPart( part.getName(), schemaType, part.getElementName(), schemaElement ));
614 }
615 }
616
617 return result.toArray( new MessagePart[result.size()] );
618 }
619 catch (Exception e)
620 {
621 SoapUI.logError( e );
622 return new MessagePart [0];
623 }
624 }
625
626 public MessagePart[] getDefaultResponseParts()
627 {
628 try
629 {
630
631 List<MessagePart> result = new ArrayList<MessagePart>();
632 WsdlContext wsdlContext = getInterface().getWsdlContext();
633 BindingOperation bindingOperation = findBindingOperation(wsdlContext.getDefinition());
634
635 if( bindingOperation == null )
636 return new MessagePart[0];
637
638
639 List<SoapHeader> headers = WsdlUtils.getSoapHeaders( bindingOperation.getBindingOutput()
640 .getExtensibilityElements());
641
642 for (int i = 0; i < headers.size(); i++)
643 {
644 SoapHeader header = headers.get( i );
645
646 Message message = wsdlContext.getDefinition().getMessage( header.getMessage() );
647 if( message == null )
648 {
649 log.error( "Missing message for header: " + header.getMessage() );
650 continue;
651 }
652
653 javax.wsdl.Part part = message.getPart( header.getPart() );
654
655 if( part != null )
656 {
657 SchemaType schemaType = WsdlUtils.getSchemaTypeForPart( wsdlContext, part );
658 SchemaGlobalElement schemaElement = WsdlUtils.getSchemaElementForPart( wsdlContext, part );
659 if( schemaType != null )
660 result.add( new WsdlHeaderPart( part.getName(), schemaType, part.getElementName(), schemaElement ));
661 }
662 else
663 log.error( "Missing part for header; " + header.getPart() );
664 }
665
666
667 javax.wsdl.Part[] parts = WsdlUtils.getOutputParts( bindingOperation );
668
669 for( int i = 0; i < parts.length; i++ )
670 {
671 javax.wsdl.Part part = parts[i];
672
673 if( !WsdlUtils.isAttachmentOutputPart( part, bindingOperation ))
674 {
675 SchemaType schemaType = WsdlUtils.getSchemaTypeForPart( wsdlContext, part );
676 SchemaGlobalElement schemaElement = WsdlUtils.getSchemaElementForPart( wsdlContext, part );
677 if( schemaType != null )
678 result.add( new WsdlContentPart( part.getName(), schemaType, part.getElementName(), schemaElement ));
679 }
680 }
681
682 return result.toArray( new MessagePart[result.size()] );
683 }
684 catch (Exception e)
685 {
686 SoapUI.logError( e );
687 return new MessagePart [0];
688 }
689 }
690
691 public FaultPart [] getFaultParts()
692 {
693 BindingOperation bindingOperation = getBindingOperation();
694 Map bindingFaults = bindingOperation.getBindingFaults();
695
696 List<FaultPart> result = new ArrayList<FaultPart>();
697 for( Object key : bindingFaults.keySet() )
698 {
699 result.add( new WsdlFaultPart( (String)key ));
700 }
701
702 return result.toArray( new FaultPart[result.size()] );
703 }
704
705 private class WsdlFaultPart extends FaultPart
706 {
707 private final String name;
708
709 public WsdlFaultPart( String name )
710 {
711 this.name = name;
712 }
713
714 @Override
715 public javax.wsdl.Part[] getWsdlParts()
716 {
717 try
718 {
719 return WsdlUtils.getFaultParts( getBindingOperation(), name );
720 }
721 catch( Exception e )
722 {
723 log.error( e.toString(), e );
724 }
725
726 return new javax.wsdl.Part[0];
727 }
728
729 @Override
730 public QName getPartElementName()
731 {
732 return null;
733 }
734
735 public String getDescription()
736 {
737 return null;
738 }
739
740 public String getName()
741 {
742 return name;
743 }
744
745 @Override
746 public SchemaType getSchemaType()
747 {
748 return null;
749 }
750
751 @Override
752 public SchemaGlobalElement getPartElement()
753 {
754 return null;
755 }}
756
757 @Override
758 public void beforeSave()
759 {
760 for( WsdlRequest request : requests )
761 request.beforeSave();
762 }
763
764 public List<? extends ModelItem> getChildren()
765 {
766 return getRequests();
767 }
768 }