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 List<javax.wsdl.Part> parts = bindingOperation.getOperation().getInput().getMessage().getOrderedParts( null );
421 if( parts == null || parts.isEmpty() )
422 return null;
423
424 javax.wsdl.Part part = parts.get( 0 );
425
426 if( part.getElementName() != null )
427 {
428 return part.getElementName();
429 }
430 else
431 {
432 return new QName( definition.getTargetNamespace(), part.getName() );
433 }
434 }
435 }
436
437 @SuppressWarnings("unchecked")
438 public QName getResponseBodyElementQName() throws Exception
439 {
440 if( isOneWay() )
441 return null;
442
443 WsdlInterface iface = getInterface();
444
445 Definition definition = iface.getWsdlContext().getDefinition();
446 BindingOperation bindingOperation = findBindingOperation( definition );
447 if( WsdlUtils.isRpc( definition, bindingOperation))
448 {
449 String ns = WsdlUtils.getSoapBodyNamespace( bindingOperation.getBindingOutput().getExtensibilityElements() );
450 if( ns == null )
451 {
452 ns = definition.getTargetNamespace();
453 }
454
455 return new QName( ns, bindingOperation.getName() + "Response" );
456 }
457 else
458 {
459 List<javax.wsdl.Part> parts = bindingOperation.getOperation().getOutput().getMessage().getOrderedParts( null );
460 if( parts == null || parts.isEmpty() )
461 return null;
462
463 javax.wsdl.Part part = parts.get( 0 );
464
465 if( part.getElementName() != null )
466 {
467 return part.getElementName();
468 }
469 else
470 {
471 return new QName( definition.getTargetNamespace(), part.getName() );
472 }
473 }
474 }
475
476 public String getStyle()
477 {
478 WsdlContext wsdlContext = iface.getWsdlContext();
479 if( !wsdlContext.isLoaded() )
480 return "<not loaded>";
481
482 try
483 {
484 Definition definition = wsdlContext.getDefinition();
485 BindingOperation bindingOperation = findBindingOperation( definition);
486
487 if( bindingOperation == null )
488 return "<missing bindingOperation>";
489
490 if( WsdlUtils.isRpc( definition, bindingOperation ))
491 {
492 return WsdlOperation.STYLE_RPC;
493 }
494 else
495 {
496 return WsdlOperation.STYLE_DOCUMENT;
497 }
498 }
499 catch (Exception e)
500 {
501 SoapUI.logError( e );
502 return "<error>";
503 }
504 }
505
506 @Override
507 public void release()
508 {
509 super.release();
510
511 for( WsdlRequest request : requests )
512 request.release();
513 }
514
515 public BindingOperation getBindingOperation()
516 {
517 try
518 {
519 return findBindingOperation( getInterface().getWsdlContext().getDefinition() );
520 }
521 catch( Exception e )
522 {
523 SoapUI.logError( e );
524 return null;
525 }
526 }
527
528 public List<Request> getRequests()
529 {
530 return new ArrayList<Request>( requests );
531 }
532
533 public MessagePart[] getDefaultRequestParts()
534 {
535 try
536 {
537
538 List<MessagePart> result = new ArrayList<MessagePart>();
539 WsdlContext wsdlContext = getInterface().getWsdlContext();
540 BindingOperation bindingOperation = findBindingOperation(wsdlContext.getDefinition());
541
542 if( bindingOperation == null )
543 return new MessagePart[0];
544
545
546 List<SoapHeader> headers = WsdlUtils.getSoapHeaders( bindingOperation.getBindingInput()
547 .getExtensibilityElements());
548
549 for (int i = 0; i < headers.size(); i++)
550 {
551 SoapHeader header = headers.get( i );
552
553 Message message = wsdlContext.getDefinition().getMessage( header.getMessage() );
554 if( message == null )
555 {
556 log.error( "Missing message for header: " + header.getMessage() );
557 continue;
558 }
559
560 javax.wsdl.Part part = message.getPart( header.getPart() );
561
562 if( part != null )
563 {
564 SchemaType schemaType = WsdlUtils.getSchemaTypeForPart( wsdlContext, part );
565 SchemaGlobalElement schemaElement = WsdlUtils.getSchemaElementForPart( wsdlContext, part );
566 if( schemaType != null )
567 result.add( new WsdlHeaderPart( part.getName(), schemaType, part.getElementName(), schemaElement ));
568 }
569 else
570 log.error( "Missing part for header; " + header.getPart() );
571 }
572
573
574 javax.wsdl.Part[] parts = WsdlUtils.getInputParts( bindingOperation );
575
576 for( int i = 0; i < parts.length; i++ )
577 {
578 javax.wsdl.Part part = parts[i];
579
580 if( !WsdlUtils.isAttachmentInputPart( part, bindingOperation ))
581 {
582 SchemaType schemaType = WsdlUtils.getSchemaTypeForPart( wsdlContext, part );
583 SchemaGlobalElement schemaElement = WsdlUtils.getSchemaElementForPart( wsdlContext, part );
584 if( schemaType != null )
585 result.add( new WsdlContentPart( part.getName(), schemaType, part.getElementName(), schemaElement ));
586 }
587 }
588
589 return result.toArray( new MessagePart[result.size()] );
590 }
591 catch (Exception e)
592 {
593 SoapUI.logError( e );
594 return new MessagePart [0];
595 }
596 }
597
598 public MessagePart[] getDefaultResponseParts()
599 {
600 try
601 {
602
603 List<MessagePart> result = new ArrayList<MessagePart>();
604 WsdlContext wsdlContext = getInterface().getWsdlContext();
605 BindingOperation bindingOperation = findBindingOperation(wsdlContext.getDefinition());
606
607 if( bindingOperation == null )
608 return new MessagePart[0];
609
610
611 List<SoapHeader> headers = WsdlUtils.getSoapHeaders( bindingOperation.getBindingOutput()
612 .getExtensibilityElements());
613
614 for (int i = 0; i < headers.size(); i++)
615 {
616 SoapHeader header = headers.get( i );
617
618 Message message = wsdlContext.getDefinition().getMessage( header.getMessage() );
619 if( message == null )
620 {
621 log.error( "Missing message for header: " + header.getMessage() );
622 continue;
623 }
624
625 javax.wsdl.Part part = message.getPart( header.getPart() );
626
627 if( part != null )
628 {
629 SchemaType schemaType = WsdlUtils.getSchemaTypeForPart( wsdlContext, part );
630 SchemaGlobalElement schemaElement = WsdlUtils.getSchemaElementForPart( wsdlContext, part );
631 if( schemaType != null )
632 result.add( new WsdlHeaderPart( part.getName(), schemaType, part.getElementName(), schemaElement ));
633 }
634 else
635 log.error( "Missing part for header; " + header.getPart() );
636 }
637
638
639 javax.wsdl.Part[] parts = WsdlUtils.getOutputParts( bindingOperation );
640
641 for( int i = 0; i < parts.length; i++ )
642 {
643 javax.wsdl.Part part = parts[i];
644
645 if( !WsdlUtils.isAttachmentOutputPart( part, bindingOperation ))
646 {
647 SchemaType schemaType = WsdlUtils.getSchemaTypeForPart( wsdlContext, part );
648 SchemaGlobalElement schemaElement = WsdlUtils.getSchemaElementForPart( wsdlContext, part );
649 if( schemaType != null )
650 result.add( new WsdlContentPart( part.getName(), schemaType, part.getElementName(), schemaElement ));
651 }
652 }
653
654 return result.toArray( new MessagePart[result.size()] );
655 }
656 catch (Exception e)
657 {
658 SoapUI.logError( e );
659 return new MessagePart [0];
660 }
661 }
662
663 public FaultPart [] getFaultParts()
664 {
665 BindingOperation bindingOperation = getBindingOperation();
666 Map bindingFaults = bindingOperation.getBindingFaults();
667
668 List<FaultPart> result = new ArrayList<FaultPart>();
669 for( Object key : bindingFaults.keySet() )
670 {
671 result.add( new WsdlFaultPart( (String)key ));
672 }
673
674 return result.toArray( new FaultPart[result.size()] );
675 }
676
677 private class WsdlFaultPart extends FaultPart
678 {
679 private final String name;
680
681 public WsdlFaultPart( String name )
682 {
683 this.name = name;
684 }
685
686 @Override
687 public javax.wsdl.Part[] getWsdlParts()
688 {
689 try
690 {
691 return WsdlUtils.getFaultParts( getBindingOperation(), name );
692 }
693 catch( Exception e )
694 {
695 log.error( e.toString(), e );
696 }
697
698 return new javax.wsdl.Part[0];
699 }
700
701 @Override
702 public QName getPartElementName()
703 {
704 return null;
705 }
706
707 public String getDescription()
708 {
709 return null;
710 }
711
712 public String getName()
713 {
714 return name;
715 }
716
717 @Override
718 public SchemaType getSchemaType()
719 {
720 return null;
721 }
722
723 @Override
724 public SchemaGlobalElement getPartElement()
725 {
726 return null;
727 }}
728
729 @Override
730 public void beforeSave()
731 {
732 for( WsdlRequest request : requests )
733 request.beforeSave();
734 }
735
736 public List<? extends ModelItem> getChildren()
737 {
738 return getRequests();
739 }
740 }