View Javadoc

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