View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
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.BindingInput;
22  import javax.wsdl.BindingOperation;
23  import javax.wsdl.BindingOutput;
24  import javax.wsdl.Definition;
25  import javax.wsdl.Message;
26  import javax.wsdl.OperationType;
27  import javax.wsdl.extensions.mime.MIMEContent;
28  import javax.wsdl.extensions.mime.MIMEMultipartRelated;
29  import javax.wsdl.extensions.mime.MIMEPart;
30  import javax.xml.namespace.QName;
31  
32  import org.apache.log4j.Logger;
33  import org.apache.xmlbeans.SchemaGlobalElement;
34  import org.apache.xmlbeans.SchemaType;
35  
36  import com.eviware.soapui.SoapUI;
37  import com.eviware.soapui.config.AnonymousTypeConfig;
38  import com.eviware.soapui.config.OperationConfig;
39  import com.eviware.soapui.config.OperationTypesConfig;
40  import com.eviware.soapui.config.WsaVersionTypeConfig;
41  import com.eviware.soapui.config.WsdlRequestConfig;
42  import com.eviware.soapui.config.PartsConfig.Part;
43  import com.eviware.soapui.impl.support.AbstractHttpOperation;
44  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.AttachmentUtils;
45  import com.eviware.soapui.impl.wsdl.support.soap.SoapMessageBuilder;
46  import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlContext;
47  import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils;
48  import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils.SoapHeader;
49  import com.eviware.soapui.model.ModelItem;
50  import com.eviware.soapui.model.iface.MessagePart;
51  import com.eviware.soapui.model.iface.Request;
52  import com.eviware.soapui.model.iface.Attachment.AttachmentEncoding;
53  import com.eviware.soapui.model.iface.MessagePart.FaultPart;
54  import com.eviware.soapui.support.UISupport;
55  
56  /***
57   * WSDL implementation of Operation, maps to a WSDL BindingOperation
58   * 
59   * @author Ole.Matzura
60   */
61  
62  public class WsdlOperation extends AbstractWsdlModelItem<OperationConfig> implements AbstractHttpOperation
63  {
64  	public static final String STYLE_DOCUMENT = "Document";
65  	public static final String STYLE_RPC = "RPC";
66  
67  	public static final String ONE_WAY = "One-Way";
68  	public static final String NOTIFICATION = "Notification";
69  	public static final String REQUEST_RESPONSE = "Request-Response";
70  	public static final String SOLICIT_RESPONSE = "Solicit-Response";
71  
72  	public final static Logger log = Logger.getLogger( WsdlOperation.class );
73  	private List<WsdlRequest> requests = new ArrayList<WsdlRequest>();
74  	private WsdlInterface iface;
75  	private ImageIcon oneWayIcon;
76  
77  	private ImageIcon notificationIcon;
78  
79  	private ImageIcon solicitResponseIcon;
80  
81  	public WsdlOperation( WsdlInterface iface, OperationConfig operationConfig )
82  	{
83  		super( operationConfig, iface, "/operation.gif" );
84  		this.iface = iface;
85  
86  		if( !operationConfig.isSetIsOneWay() )
87  		{
88  			operationConfig.setIsOneWay( false );
89  		}
90  
91  		List<WsdlRequestConfig> requestConfigs = getConfig().getCallList();
92  		for( WsdlRequestConfig config : requestConfigs )
93  		{
94  			requests.add( new WsdlRequest( this, config ) );
95  		}
96  
97  		oneWayIcon = UISupport.createImageIcon( "/onewayoperation.gif" );
98  		notificationIcon = UISupport.createImageIcon( "/notificationoperation.gif" );
99  		solicitResponseIcon = UISupport.createImageIcon( "/solicitresponseoperation.gif" );
100 	}
101 
102 	public String getAction()
103 	{
104 		String action = getConfig().getAction();
105 		return action == null ? "" : action;
106 	}
107 
108 	public WsdlRequest getRequestAt( int index )
109 	{
110 		return requests.get( index );
111 	}
112 
113 	public WsdlRequest getRequestByName( String requestName )
114 	{
115 		return ( WsdlRequest )getWsdlModelItemByName( requests, requestName );
116 	}
117 
118 	public int getRequestCount()
119 	{
120 		return requests.size();
121 	}
122 
123 	@Override
124 	public ImageIcon getIcon()
125 	{
126 		if( isOneWay() )
127 		{
128 			return oneWayIcon;
129 		}
130 		else if( isSolicitResponse() )
131 		{
132 			return solicitResponseIcon;
133 		}
134 		else if( isNotification() )
135 		{
136 			return notificationIcon;
137 		}
138 		else
139 		{
140 			return super.getIcon();
141 		}
142 	}
143 
144 	public WsdlRequest addNewRequest( String name )
145 	{
146 		WsdlRequest requestImpl = new WsdlRequest( this, getConfig().addNewCall() );
147 		requestImpl.setName( name );
148 		requests.add( requestImpl );
149 
150 		if( !getInterface().getWsaVersion().equals( WsaVersionTypeConfig.NONE.toString() ) )
151 		{
152 			requestImpl.setWsAddressing( true );
153 		}
154 		WsdlUtils.setDefaultWsaAction( requestImpl.getWsaConfig(), false );
155 		WsdlUtils.getAnonymous( this );
156 
157 		( getInterface() ).fireRequestAdded( requestImpl );
158 		return requestImpl;
159 	}
160 
161 	public WsdlInterface getInterface()
162 	{
163 		return iface;
164 	}
165 
166 	public void setAction( String soapAction )
167 	{
168 		String old = getAction();
169 		getConfig().setAction( soapAction );
170 		notifyPropertyChanged( ACTION_PROPERTY, old, soapAction );
171 	}
172 
173 	public String createRequest( boolean buildOptional )
174 	{
175 		if( iface.getBindingName() == null )
176 		{
177 			UISupport.showErrorMessage( "Missing binding name, please try to refresh "
178 					+ "Interface\nfor request generation to work correctly" );
179 			return null;
180 		}
181 
182 		if( getBindingOperationName() == null )
183 		{
184 			UISupport.showErrorMessage( "Missing bindingOperation name, please try to refresh "
185 					+ "Interface\nfor request generation to work correctly" );
186 			return null;
187 		}
188 
189 		try
190 		{
191 			SoapMessageBuilder builder = iface.getMessageBuilder();
192 			BindingOperation bindingOperation = findBindingOperation( iface.getWsdlContext().getDefinition() );
193 
194 			if( bindingOperation == null )
195 			{
196 				UISupport.showErrorMessage( "Failed to find bindingOperation, please try to refresh "
197 						+ "Interface\nfor request generation to work correctly" );
198 				return null;
199 			}
200 
201 			OperationType type = bindingOperation.getOperation().getStyle();
202 			if( OperationType.ONE_WAY.equals( type ) || OperationType.REQUEST_RESPONSE.equals( type ) )
203 			{
204 				return builder.buildSoapMessageFromInput( bindingOperation, buildOptional );
205 			}
206 			else
207 			{
208 				return builder.buildSoapMessageFromOutput( bindingOperation, buildOptional );
209 			}
210 		}
211 		catch( Exception e )
212 		{
213 			SoapUI.logError( e );
214 			return null;
215 		}
216 	}
217 
218 	public String createResponse( boolean buildOptional )
219 	{
220 		if( isUnidirectional() )
221 		{
222 			return null;
223 		}
224 
225 		if( iface.getBindingName() == null )
226 		{
227 			UISupport.showErrorMessage( "Missing binding name, please try to refresh "
228 					+ "Interface\nfor request generation to work correctly" );
229 			return null;
230 		}
231 
232 		if( getBindingOperationName() == null )
233 		{
234 			UISupport.showErrorMessage( "Missing bindingOperation name, please try to refresh "
235 					+ "Interface\nfor request generation to work correctly" );
236 			return null;
237 		}
238 
239 		try
240 		{
241 			SoapMessageBuilder builder = iface.getMessageBuilder();
242 			BindingOperation bindingOperation = findBindingOperation( iface.getWsdlContext().getDefinition() );
243 
244 			if( bindingOperation == null )
245 			{
246 				UISupport.showErrorMessage( "Failed to find bindingOperation, please try to refresh "
247 						+ "Interface\nfor request generation to work correctly" );
248 				return null;
249 			}
250 
251 			if( isRequestResponse() )
252 			{
253 				return builder.buildSoapMessageFromOutput( bindingOperation, buildOptional );
254 			}
255 			else
256 			{
257 				return builder.buildSoapMessageFromInput( bindingOperation, buildOptional );
258 			}
259 		}
260 		catch( Exception e )
261 		{
262 			SoapUI.logError( e );
263 			return null;
264 		}
265 	}
266 
267 	public BindingOperation findBindingOperation( Definition definition )
268 	{
269 		String bindingOperationName = getConfig().getBindingOperationName();
270 		return iface.findBindingOperation( definition, bindingOperationName, getInputName(), getOutputName() );
271 	}
272 
273 	public void removeRequest( WsdlRequest request )
274 	{
275 		int ix = requests.indexOf( request );
276 		requests.remove( ix );
277 
278 		try
279 		{
280 			( getInterface() ).fireRequestRemoved( request );
281 		}
282 		finally
283 		{
284 			request.release();
285 			getConfig().removeCall( ix );
286 		}
287 	}
288 
289 	public OperationType getOperationType()
290 	{
291 		OperationConfig config = getConfig();
292 
293 		// Backwards compatibility:
294 		if( !config.isSetType() )
295 		{
296 			if( config.getIsOneWay() )
297 			{
298 				config.setType( OperationTypesConfig.ONE_WAY );
299 				return OperationType.ONE_WAY;
300 			}
301 			else
302 			{
303 				config.setType( OperationTypesConfig.REQUEST_RESPONSE );
304 				return OperationType.REQUEST_RESPONSE;
305 			}
306 		}
307 
308 		OperationTypesConfig.Enum type = config.getType();
309 		if( OperationTypesConfig.ONE_WAY.equals( type ) )
310 		{
311 			return OperationType.ONE_WAY;
312 		}
313 		else if( OperationTypesConfig.NOTIFICATION.equals( type ) )
314 		{
315 			return OperationType.NOTIFICATION;
316 		}
317 		else if( OperationTypesConfig.SOLICIT_RESPONSE.equals( type ) )
318 		{
319 			return OperationType.SOLICIT_RESPONSE;
320 		}
321 		else
322 		{
323 			return OperationType.REQUEST_RESPONSE;
324 		}
325 	}
326 
327 	public void setOperationType( OperationType type )
328 	{
329 		OperationConfig config = getConfig();
330 		if( type == null )
331 		{
332 			if( config.isSetType() )
333 				config.unsetType();
334 		}
335 		else
336 		{
337 			if( OperationType.ONE_WAY.equals( type ) )
338 			{
339 				config.setType( OperationTypesConfig.ONE_WAY );
340 			}
341 			else if( OperationType.NOTIFICATION.equals( type ) )
342 			{
343 				config.setType( OperationTypesConfig.NOTIFICATION );
344 			}
345 			else if( OperationType.SOLICIT_RESPONSE.equals( type ) )
346 			{
347 				config.setType( OperationTypesConfig.SOLICIT_RESPONSE );
348 			}
349 			else
350 			{
351 				config.setType( OperationTypesConfig.REQUEST_RESPONSE );
352 			}
353 		}
354 	}
355 
356 	public String getBindingOperationName()
357 	{
358 		return getConfig().getBindingOperationName();
359 	}
360 
361 	public void setBindingOperationName( String name )
362 	{
363 		getConfig().setBindingOperationName( name );
364 	}
365 
366 	public void setInputName( String name )
367 	{
368 		getConfig().setInputName( name );
369 	}
370 
371 	public String getInputName()
372 	{
373 		String inputName = getConfig().getInputName();
374 		return inputName == null || inputName.trim().length() == 0 ? null : inputName;
375 	}
376 
377 	public void setOutputName( String name )
378 	{
379 		if( name == null )
380 		{
381 			if( getConfig().isSetOutputName() )
382 				getConfig().unsetOutputName();
383 		}
384 		else
385 			getConfig().setOutputName( name );
386 	}
387 
388 	public String getOutputName()
389 	{
390 		String outputName = getConfig().getOutputName();
391 		return outputName == null || outputName.trim().length() == 0 ? null : outputName;
392 	}
393 
394 	public String getAnonymous()
395 	{
396 		if( getConfig().getAnonymous() != null )
397 		{
398 			if( getConfig().getAnonymous().equals( AnonymousTypeConfig.PROHIBITED ) )
399 			{
400 				return AnonymousTypeConfig.PROHIBITED.toString();
401 			}
402 			else if( getConfig().getAnonymous().equals( AnonymousTypeConfig.REQUIRED ) )
403 			{
404 				return AnonymousTypeConfig.REQUIRED.toString();
405 			}
406 		}
407 
408 		return AnonymousTypeConfig.OPTIONAL.toString();
409 	}
410 
411 	public void setAnonymous( String anonymous )
412 	{
413 		// getConfig().setAnonymous(AnonymousTypeConfig.Enum.forString(arg0));
414 		if( anonymous.equals( AnonymousTypeConfig.REQUIRED.toString() ) )
415 			getConfig().setAnonymous( AnonymousTypeConfig.REQUIRED );
416 		else if( anonymous.equals( AnonymousTypeConfig.PROHIBITED.toString() ) )
417 			getConfig().setAnonymous( AnonymousTypeConfig.PROHIBITED );
418 		else
419 			getConfig().setAnonymous( AnonymousTypeConfig.OPTIONAL );
420 
421 	}
422 
423 	public boolean isOneWay()
424 	{
425 		return OperationType.ONE_WAY.equals( getOperationType() );
426 	}
427 
428 	public boolean isNotification()
429 	{
430 		return OperationType.NOTIFICATION.equals( getOperationType() );
431 	}
432 
433 	public boolean isSolicitResponse()
434 	{
435 		return OperationType.SOLICIT_RESPONSE.equals( getOperationType() );
436 	}
437 
438 	public boolean isRequestResponse()
439 	{
440 		return OperationType.REQUEST_RESPONSE.equals( getOperationType() );
441 	}
442 
443 	public boolean isUnidirectional()
444 	{
445 		return isOneWay() || isNotification();
446 	}
447 
448 	public boolean isBidirectional()
449 	{
450 		return !isUnidirectional();
451 	}
452 
453 	public void initFromBindingOperation( BindingOperation operation )
454 	{
455 		setAction( WsdlUtils.getSoapAction( operation ) );
456 		setName( operation.getOperation().getName() );
457 		setBindingOperationName( operation.getName() );
458 		setOperationType( operation.getOperation().getStyle() );
459 
460 		BindingInput bindingInput = operation.getBindingInput();
461 		BindingOutput bindingOutput = operation.getBindingOutput();
462 
463 		setOutputName( bindingOutput != null ? bindingOutput.getName() : null );
464 		setInputName( bindingInput != null ? bindingInput.getName() : null );
465 
466 		initAttachments( operation );
467 	}
468 
469 	@SuppressWarnings( "unchecked" )
470 	private void initAttachments( BindingOperation operation )
471 	{
472 		if( getConfig().isSetRequestParts() )
473 			getConfig().unsetRequestParts();
474 
475 		if( getConfig().isSetResponseParts() )
476 			getConfig().unsetResponseParts();
477 
478 		BindingOutput bindingOutput = operation.getBindingOutput();
479 		BindingInput bindingInput = operation.getBindingInput();
480 
481 		if( bindingOutput != null )
482 		{
483 			MIMEMultipartRelated multipartOutput = WsdlUtils.getExtensiblityElement( bindingOutput
484 					.getExtensibilityElements(), MIMEMultipartRelated.class );
485 
486 			getConfig().setReceivesAttachments( multipartOutput != null );
487 			if( multipartOutput != null )
488 			{
489 				List<MIMEPart> parts = multipartOutput.getMIMEParts();
490 				Map<String, Part> partMap = new HashMap<String, Part>();
491 
492 				for( int c = 0; c < parts.size(); c++ )
493 				{
494 					List<MIMEContent> contentParts = WsdlUtils.getExtensiblityElements( parts.get( c )
495 							.getExtensibilityElements(), MIMEContent.class );
496 
497 					for( MIMEContent content : contentParts )
498 					{
499 						Part part = partMap.get( content.getPart() );
500 						if( part != null )
501 						{
502 							if( !part.getContentTypeList().contains( content.getType() ) )
503 								part.addContentType( content.getType() );
504 						}
505 						else
506 						{
507 							if( !getConfig().isSetResponseParts() )
508 								getConfig().addNewResponseParts();
509 
510 							Part responsePart = getConfig().getResponseParts().addNewPart();
511 							responsePart.addContentType( content.getType() );
512 							responsePart.setName( content.getPart() );
513 
514 							partMap.put( responsePart.getName(), responsePart );
515 						}
516 					}
517 				}
518 			}
519 		}
520 
521 		if( bindingInput != null )
522 		{
523 			MIMEMultipartRelated multipartInput = WsdlUtils.getExtensiblityElement( bindingInput
524 					.getExtensibilityElements(), MIMEMultipartRelated.class );
525 
526 			getConfig().setSendsAttachments( multipartInput != null );
527 			if( multipartInput != null )
528 			{
529 				List<MIMEPart> parts = multipartInput.getMIMEParts();
530 				Map<String, Part> partMap = new HashMap<String, Part>();
531 
532 				for( int c = 0; c < parts.size(); c++ )
533 				{
534 					List<MIMEContent> contentParts = WsdlUtils.getExtensiblityElements( parts.get( c )
535 							.getExtensibilityElements(), MIMEContent.class );
536 
537 					for( MIMEContent content : contentParts )
538 					{
539 						Part part = partMap.get( content.getPart() );
540 						if( part != null )
541 						{
542 							if( !part.getContentTypeList().contains( content.getType() ) )
543 								part.addContentType( content.getType() );
544 						}
545 						else
546 						{
547 							if( !getConfig().isSetRequestParts() )
548 								getConfig().addNewRequestParts();
549 
550 							Part requestPart = getConfig().getRequestParts().addNewPart();
551 							requestPart.addContentType( content.getType() );
552 							requestPart.setName( content.getPart() );
553 
554 							partMap.put( requestPart.getName(), requestPart );
555 						}
556 					}
557 				}
558 			}
559 		}
560 	}
561 
562 	public boolean getReceivesAttachments()
563 	{
564 		return getConfig().getReceivesAttachments();
565 	}
566 
567 	public boolean getSendsAttachments()
568 	{
569 		return getConfig().getSendsAttachments();
570 	}
571 
572 	@SuppressWarnings( "unchecked" )
573 	public QName getRequestBodyElementQName() throws Exception
574 	{
575 		WsdlInterface iface = getInterface();
576 
577 		Definition definition = iface.getWsdlContext().getDefinition();
578 		BindingOperation bindingOperation = findBindingOperation( definition );
579 		if( WsdlUtils.isRpc( definition, bindingOperation ) )
580 		{
581 			BindingInput bindingInput = bindingOperation.getBindingInput();
582 			if( bindingInput == null )
583 				return null;
584 
585 			String ns = WsdlUtils.getSoapBodyNamespace( bindingInput.getExtensibilityElements() );
586 			if( ns == null )
587 			{
588 				ns = definition.getTargetNamespace();
589 			}
590 
591 			return new QName( ns, bindingOperation.getName() );
592 		}
593 		else
594 		{
595 			Message message = bindingOperation.getOperation().getInput().getMessage();
596 			List<javax.wsdl.Part> parts = message.getOrderedParts( null );
597 			if( parts == null || parts.isEmpty() )
598 				return null;
599 
600 			int ix = 0;
601 			javax.wsdl.Part part = parts.get( 0 );
602 
603 			while( part != null
604 					&& ( WsdlUtils.isAttachmentInputPart( part, bindingOperation ) || WsdlUtils.isHeaderInputPart( part,
605 							message, bindingOperation ) ) )
606 			{
607 				ix++ ;
608 				if( ix < parts.size() )
609 					part = parts.get( ix );
610 				else
611 					part = null;
612 			}
613 
614 			if( part == null )
615 				return null;
616 
617 			if( part.getElementName() != null )
618 			{
619 				return part.getElementName();
620 			}
621 			else
622 			{
623 				// return new QName( definition.getTargetNamespace(), part.getName()
624 				// );
625 				// changed to comply with soapmessagebuilder -> behaviour is not
626 				// really defined
627 				return new QName( part.getName() );
628 			}
629 		}
630 	}
631 
632 	@SuppressWarnings( "unchecked" )
633 	public QName getResponseBodyElementQName() throws Exception
634 	{
635 		if( isUnidirectional() )
636 			return null;
637 
638 		WsdlInterface iface = getInterface();
639 
640 		Definition definition = iface.getWsdlContext().getDefinition();
641 		BindingOperation bindingOperation = findBindingOperation( definition );
642 		if( WsdlUtils.isRpc( definition, bindingOperation ) )
643 		{
644 			BindingOutput bindingOutput = bindingOperation.getBindingOutput();
645 			String ns = bindingOutput == null ? null : WsdlUtils.getSoapBodyNamespace( bindingOutput
646 					.getExtensibilityElements() );
647 			if( ns == null )
648 			{
649 				ns = definition.getTargetNamespace();
650 			}
651 
652 			return new QName( ns, bindingOperation.getName() + "Response" );
653 		}
654 		else
655 		{
656 			Message message = bindingOperation.getOperation().getOutput().getMessage();
657 			List<javax.wsdl.Part> parts = message.getOrderedParts( null );
658 			if( parts == null || parts.isEmpty() )
659 				return null;
660 
661 			int ix = 0;
662 			javax.wsdl.Part part = parts.get( 0 );
663 
664 			while( part != null
665 					&& ( WsdlUtils.isAttachmentOutputPart( part, bindingOperation ) || WsdlUtils.isHeaderOutputPart( part,
666 							message, bindingOperation ) ) )
667 			{
668 				ix++ ;
669 				if( ix < parts.size() )
670 					part = parts.get( ix );
671 				else
672 					part = null;
673 			}
674 
675 			if( part == null )
676 				return null;
677 
678 			if( part.getElementName() != null )
679 			{
680 				return part.getElementName();
681 			}
682 			else
683 			{
684 				// return new QName( definition.getTargetNamespace(), part.getName()
685 				// );
686 				return new QName( part.getName() );
687 			}
688 		}
689 	}
690 
691 	public String getStyle()
692 	{
693 		WsdlContext wsdlContext = iface.getWsdlContext();
694 		if( !wsdlContext.isLoaded() )
695 			return "<not loaded>";
696 
697 		try
698 		{
699 			Definition definition = wsdlContext.getDefinition();
700 			BindingOperation bindingOperation = findBindingOperation( definition );
701 
702 			if( bindingOperation == null )
703 				return "<missing bindingOperation>";
704 
705 			if( WsdlUtils.isRpc( definition, bindingOperation ) )
706 			{
707 				return WsdlOperation.STYLE_RPC;
708 			}
709 			else
710 			{
711 				return WsdlOperation.STYLE_DOCUMENT;
712 			}
713 		}
714 		catch( Exception e )
715 		{
716 			SoapUI.logError( e );
717 			return "<error>";
718 		}
719 	}
720 
721 	public String getType()
722 	{
723 		if( isOneWay() )
724 		{
725 			return ONE_WAY;
726 		}
727 		else if( isNotification() )
728 		{
729 			return NOTIFICATION;
730 		}
731 		else if( isSolicitResponse() )
732 		{
733 			return SOLICIT_RESPONSE;
734 		}
735 		else
736 		{
737 			return REQUEST_RESPONSE;
738 		}
739 	}
740 
741 	@Override
742 	public void release()
743 	{
744 		super.release();
745 
746 		for( WsdlRequest request : requests )
747 			request.release();
748 	}
749 
750 	public BindingOperation getBindingOperation()
751 	{
752 		try
753 		{
754 			return findBindingOperation( getInterface().getWsdlContext().getDefinition() );
755 		}
756 		catch( Exception e )
757 		{
758 			SoapUI.logError( e );
759 			return null;
760 		}
761 	}
762 
763 	public List<Request> getRequestList()
764 	{
765 		return new ArrayList<Request>( requests );
766 	}
767 
768 	public MessagePart[] getDefaultRequestParts()
769 	{
770 		try
771 		{
772 			// init
773 			List<MessagePart> result = new ArrayList<MessagePart>();
774 			WsdlContext wsdlContext = getInterface().getWsdlContext();
775 			BindingOperation bindingOperation = findBindingOperation( wsdlContext.getDefinition() );
776 
777 			if( bindingOperation == null )
778 				return new MessagePart[0];
779 
780 			// header parts
781 			BindingInput bindingInput = bindingOperation.getBindingInput();
782 			if( bindingInput == null )
783 				return new MessagePart[0];
784 
785 			List<SoapHeader> headers = WsdlUtils.getSoapHeaders( bindingInput.getExtensibilityElements() );
786 
787 			for( int i = 0; i < headers.size(); i++ )
788 			{
789 				SoapHeader header = headers.get( i );
790 
791 				Message message = wsdlContext.getDefinition().getMessage( header.getMessage() );
792 				if( message == null )
793 				{
794 					log.error( "Missing message for header: " + header.getMessage() );
795 					continue;
796 				}
797 
798 				javax.wsdl.Part part = message.getPart( header.getPart() );
799 
800 				if( part != null )
801 				{
802 					SchemaType schemaType = WsdlUtils.getSchemaTypeForPart( wsdlContext, part );
803 					SchemaGlobalElement schemaElement = WsdlUtils.getSchemaElementForPart( wsdlContext, part );
804 					if( schemaType != null )
805 						result.add( new WsdlHeaderPart( part.getName(), schemaType, part.getElementName(), schemaElement ) );
806 				}
807 				else
808 					log.error( "Missing part for header; " + header.getPart() );
809 			}
810 
811 			// content parts
812 			javax.wsdl.Part[] parts = WsdlUtils.getInputParts( bindingOperation );
813 
814 			for( int i = 0; i < parts.length; i++ )
815 			{
816 				javax.wsdl.Part part = parts[i];
817 
818 				if( !WsdlUtils.isAttachmentInputPart( part, bindingOperation ) )
819 				{
820 					SchemaType schemaType = WsdlUtils.getSchemaTypeForPart( wsdlContext, part );
821 					SchemaGlobalElement schemaElement = WsdlUtils.getSchemaElementForPart( wsdlContext, part );
822 					if( schemaType != null )
823 						result.add( new WsdlContentPart( part.getName(), schemaType, part.getElementName(), schemaElement ) );
824 				}
825 			}
826 
827 			return result.toArray( new MessagePart[result.size()] );
828 		}
829 		catch( Exception e )
830 		{
831 			SoapUI.logError( e );
832 			return new MessagePart[0];
833 		}
834 	}
835 
836 	public MessagePart[] getDefaultResponseParts()
837 	{
838 		try
839 		{
840 			// init
841 			List<MessagePart> result = new ArrayList<MessagePart>();
842 			WsdlContext wsdlContext = getInterface().getWsdlContext();
843 			BindingOperation bindingOperation = findBindingOperation( wsdlContext.getDefinition() );
844 
845 			if( bindingOperation == null )
846 				return new MessagePart[0];
847 
848 			// header parts
849 			BindingOutput bindingOutput = bindingOperation.getBindingOutput();
850 			if( bindingOutput == null )
851 				return new MessagePart[0];
852 
853 			List<SoapHeader> headers = WsdlUtils.getSoapHeaders( bindingOutput.getExtensibilityElements() );
854 
855 			for( int i = 0; i < headers.size(); i++ )
856 			{
857 				SoapHeader header = headers.get( i );
858 
859 				Message message = wsdlContext.getDefinition().getMessage( header.getMessage() );
860 				if( message == null )
861 				{
862 					log.error( "Missing message for header: " + header.getMessage() );
863 					continue;
864 				}
865 
866 				javax.wsdl.Part part = message.getPart( header.getPart() );
867 
868 				if( part != null )
869 				{
870 					SchemaType schemaType = WsdlUtils.getSchemaTypeForPart( wsdlContext, part );
871 					SchemaGlobalElement schemaElement = WsdlUtils.getSchemaElementForPart( wsdlContext, part );
872 					if( schemaType != null )
873 						result.add( new WsdlHeaderPart( part.getName(), schemaType, part.getElementName(), schemaElement ) );
874 				}
875 				else
876 					log.error( "Missing part for header; " + header.getPart() );
877 			}
878 
879 			// content parts
880 			javax.wsdl.Part[] parts = WsdlUtils.getOutputParts( bindingOperation );
881 
882 			for( int i = 0; i < parts.length; i++ )
883 			{
884 				javax.wsdl.Part part = parts[i];
885 
886 				if( !WsdlUtils.isAttachmentOutputPart( part, bindingOperation ) )
887 				{
888 					SchemaType schemaType = WsdlUtils.getSchemaTypeForPart( wsdlContext, part );
889 					SchemaGlobalElement schemaElement = WsdlUtils.getSchemaElementForPart( wsdlContext, part );
890 					if( schemaType != null )
891 						result.add( new WsdlContentPart( part.getName(), schemaType, part.getElementName(), schemaElement ) );
892 				}
893 			}
894 
895 			return result.toArray( new MessagePart[result.size()] );
896 		}
897 		catch( Exception e )
898 		{
899 			SoapUI.logError( e );
900 			return new MessagePart[0];
901 		}
902 	}
903 
904 	public FaultPart[] getFaultParts()
905 	{
906 		BindingOperation bindingOperation = getBindingOperation();
907 		Map<?, ?> bindingFaults = bindingOperation.getBindingFaults();
908 
909 		List<FaultPart> result = new ArrayList<FaultPart>();
910 		for( Object key : bindingFaults.keySet() )
911 		{
912 			result.add( new WsdlFaultPart( ( String )key ) );
913 		}
914 
915 		return result.toArray( new FaultPart[result.size()] );
916 	}
917 
918 	private class WsdlFaultPart extends FaultPart
919 	{
920 		private final String name;
921 
922 		public WsdlFaultPart( String name )
923 		{
924 			this.name = name;
925 		}
926 
927 		@Override
928 		public javax.wsdl.Part[] getWsdlParts()
929 		{
930 			try
931 			{
932 				return WsdlUtils.getFaultParts( getBindingOperation(), name );
933 			}
934 			catch( Exception e )
935 			{
936 				log.error( e.toString(), e );
937 			}
938 
939 			return new javax.wsdl.Part[0];
940 		}
941 
942 		@Override
943 		public QName getPartElementName()
944 		{
945 			return null;
946 		}
947 
948 		public String getDescription()
949 		{
950 			return null;
951 		}
952 
953 		public String getName()
954 		{
955 			return name;
956 		}
957 
958 		@Override
959 		public SchemaType getSchemaType()
960 		{
961 			return null;
962 		}
963 
964 		@Override
965 		public SchemaGlobalElement getPartElement()
966 		{
967 			return null;
968 		}
969 	}
970 
971 	public List<? extends ModelItem> getChildren()
972 	{
973 		return getRequestList();
974 	}
975 
976 	public AttachmentEncoding getAttachmentEncoding( String part, boolean isRequest )
977 	{
978 		return AttachmentUtils.getAttachmentEncoding( this, part, !isRequest );
979 	}
980 }