View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 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.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 			// fall back to this behaviour for WSDL4j 1.5.0 compatibility
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       // bindingOutput is null for oneway operations
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 			// init
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 			// header parts
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 			// content parts
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 			// init
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 			// header parts
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 			// content parts
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 }