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