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.Arrays;
17  import java.util.HashMap;
18  import java.util.HashSet;
19  import java.util.Iterator;
20  import java.util.List;
21  import java.util.Map;
22  import java.util.Set;
23  
24  import javax.wsdl.Binding;
25  import javax.wsdl.BindingOperation;
26  import javax.wsdl.Definition;
27  import javax.wsdl.Port;
28  import javax.wsdl.Service;
29  import javax.xml.namespace.QName;
30  
31  import org.apache.log4j.Logger;
32  
33  import com.eviware.soapui.config.DefinitionCacheConfig;
34  import com.eviware.soapui.config.EndpointConfig;
35  import com.eviware.soapui.config.EndpointsConfig;
36  import com.eviware.soapui.config.InterfaceConfig;
37  import com.eviware.soapui.config.OperationConfig;
38  import com.eviware.soapui.config.SoapVersionTypesConfig;
39  import com.eviware.soapui.impl.actions.ShowDesktopPanelAction;
40  import com.eviware.soapui.impl.wsdl.actions.iface.ExportDefinitionAction;
41  import com.eviware.soapui.impl.wsdl.actions.iface.GenerateMockServiceAction;
42  import com.eviware.soapui.impl.wsdl.actions.iface.GenerateTestSuiteAction;
43  import com.eviware.soapui.impl.wsdl.actions.iface.InterfaceEndpointsAction;
44  import com.eviware.soapui.impl.wsdl.actions.iface.RemoveInterfaceAction;
45  import com.eviware.soapui.impl.wsdl.actions.iface.UpdateInterfaceAction;
46  import com.eviware.soapui.impl.wsdl.actions.iface.tools.axis1.Axis1XWSDL2JavaAction;
47  import com.eviware.soapui.impl.wsdl.actions.iface.tools.axis2.Axis2WSDL2CodeAction;
48  import com.eviware.soapui.impl.wsdl.actions.iface.tools.dotnet.DotNetWsdlAction;
49  import com.eviware.soapui.impl.wsdl.actions.iface.tools.gsoap.GSoapAction;
50  import com.eviware.soapui.impl.wsdl.actions.iface.tools.jaxb.JaxbXjcAction;
51  import com.eviware.soapui.impl.wsdl.actions.iface.tools.jbossws.JBossWSConsumeAction;
52  import com.eviware.soapui.impl.wsdl.actions.iface.tools.jbossws.WSToolsRegenerateJava2WsdlAction;
53  import com.eviware.soapui.impl.wsdl.actions.iface.tools.jbossws.WSToolsWsdl2JavaAction;
54  import com.eviware.soapui.impl.wsdl.actions.iface.tools.oracle.OracleWsaGenProxyAction;
55  import com.eviware.soapui.impl.wsdl.actions.iface.tools.tcpmon.TcpMonAction;
56  import com.eviware.soapui.impl.wsdl.actions.iface.tools.wscompile.WSCompileAction;
57  import com.eviware.soapui.impl.wsdl.actions.iface.tools.wsi.WSIAnalyzeAction;
58  import com.eviware.soapui.impl.wsdl.actions.iface.tools.wsimport.WSImportAction;
59  import com.eviware.soapui.impl.wsdl.actions.iface.tools.xfire.XFireAction;
60  import com.eviware.soapui.impl.wsdl.actions.iface.tools.xmlbeans.XmlBeans2Action;
61  import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
62  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
63  import com.eviware.soapui.impl.wsdl.support.soap.SoapMessageBuilder;
64  import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
65  import com.eviware.soapui.impl.wsdl.support.wsdl.CachedWsdlLoader;
66  import com.eviware.soapui.impl.wsdl.support.wsdl.UrlWsdlLoader;
67  import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlContext;
68  import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlLoader;
69  import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils;
70  import com.eviware.soapui.model.iface.Interface;
71  import com.eviware.soapui.model.iface.InterfaceListener;
72  import com.eviware.soapui.model.iface.Operation;
73  import com.eviware.soapui.settings.WsdlSettings;
74  import com.eviware.soapui.support.UISupport;
75  import com.eviware.soapui.support.action.ActionExtensionPoint;
76  import com.eviware.soapui.support.action.ActionSupport;
77  import com.eviware.soapui.support.action.DefaultActionList;
78  import com.eviware.soapui.support.types.StringList;
79  
80  /***
81   * WSDL implementation of Interface, maps to a WSDL Binding
82   * 
83   * @author Ole.Matzura
84   */
85  
86  public class WsdlInterface extends AbstractWsdlModelItem<InterfaceConfig> implements Interface
87  {
88  	public static final String STYLE_DOCUMENT = "Document";
89  	public static final String STYLE_RPC = "RPC";
90  
91     public static final String JBOSSWS_ACTIONS = "jbossws";
92     public static final String WSTOOLS_ACTIONS = "wstools";
93     public static final String XML_ACTIONS = "xml";
94  
95  	private final static Logger log = Logger.getLogger( WsdlInterface.class );
96  	
97     private List<WsdlOperation> operations = new ArrayList<WsdlOperation>();
98     private WsdlProject project;
99     private SoapMessageBuilder soapMessageBuilder;
100    private WsdlContext wsdlContext;
101    private Set<InterfaceListener> listeners = new HashSet<InterfaceListener>();
102    private DefaultActionList generateActions;
103    
104    public WsdlInterface( WsdlProject project, InterfaceConfig interfaceConfig )
105    {
106    	super( interfaceConfig, project, "/interface2.gif" );
107    	
108       this.project = project;
109       
110       if( interfaceConfig.getEndpoints() == null )
111          interfaceConfig.addNewEndpoints();
112       
113       List<OperationConfig> operationConfigs = interfaceConfig.getOperationList();
114       for (int i = 0; i < operationConfigs.size(); i++)
115       {
116          operations.add( new WsdlOperation( this, operationConfigs.get(i) ));
117       }
118       
119       buildActions();
120    }
121 
122 	private void buildActions()
123 	{
124 		generateActions = new DefaultActionList( "Generate" );
125       generateActions.addAction( new ActionExtensionPoint( this, WSTOOLS_ACTIONS ) );
126 		generateActions.addAction( new WSToolsWsdl2JavaAction( this ));
127 		generateActions.addAction( new JBossWSConsumeAction( this ));
128       generateActions.addAction( ActionSupport.SEPARATOR_ACTION );
129       generateActions.addAction( new ActionExtensionPoint( this, JBOSSWS_ACTIONS ) );
130       generateActions.addAction( new WSCompileAction( this ));
131       generateActions.addAction( new WSImportAction( this ));
132       generateActions.addAction( ActionSupport.SEPARATOR_ACTION );
133       generateActions.addAction( new Axis1XWSDL2JavaAction( this ));
134       generateActions.addAction( new Axis2WSDL2CodeAction( this ));
135       generateActions.addAction( new XFireAction( this ));
136       generateActions.addAction( new OracleWsaGenProxyAction( this ));
137       generateActions.addAction( ActionSupport.SEPARATOR_ACTION );
138       generateActions.addAction( new ActionExtensionPoint( this, XML_ACTIONS ) );
139       generateActions.addAction( new JaxbXjcAction( this ));
140       generateActions.addAction( new XmlBeans2Action( this ));
141       generateActions.addAction( ActionSupport.SEPARATOR_ACTION );
142       generateActions.addAction( new DotNetWsdlAction( this ));
143       generateActions.addAction( new GSoapAction( this ));
144       
145       addAction( new ShowDesktopPanelAction( "Open Interface Viewer", "Opens the Interface Viewer for this Interface", this ));
146       addAction( ActionSupport.SEPARATOR_ACTION );
147       addAction( new ActionSupport.ActionListAction( generateActions ));
148       addAction( new WSToolsRegenerateJava2WsdlAction( this ));
149       addAction( ActionSupport.SEPARATOR_ACTION );
150       addAction( new WSIAnalyzeAction( this ));
151       addAction( new TcpMonAction( this ));
152       addAction( ActionSupport.SEPARATOR_ACTION );
153       addAction( new GenerateTestSuiteAction( this ));
154       addAction( new GenerateMockServiceAction( this ));
155       addAction( ActionSupport.SEPARATOR_ACTION );
156       addAction( new InterfaceEndpointsAction( this ) );
157       addAction( new UpdateInterfaceAction( this ) );
158       addAction( new ExportDefinitionAction( this ) );
159       addAction( ActionSupport.SEPARATOR_ACTION );
160       addAction( new RemoveInterfaceAction( this ) );
161       addAction( new ShowOnlineHelpAction( HelpUrls.INTERFACE_HELP_URL ));
162 	}
163 
164    public DefaultActionList getGenerateActions()
165    {
166       return generateActions;
167    }
168 
169 	public String[] getEndpoints()
170    {
171       EndpointsConfig endpoints = getConfig().getEndpoints();
172       List<EndpointConfig> endpointArray = endpoints.getEndpointList();
173       
174       String [] result = new String[endpointArray.size()];
175       
176       for( int c = 0; c < result.length; c++ )
177       {
178       	EndpointConfig endpoint = endpointArray.get(c);
179       	if( endpoint.isSetLabel() )
180       		result[c] = endpoint.getLabel();
181       	else
182       		result[c] = endpoint.getStringValue();
183       }
184       
185 		return result; 
186    }
187 
188    public WsdlOperation getOperationAt(int index)
189    {
190       return operations.get(index);
191    }
192 
193    public int getOperationCount()
194    {
195       return operations.size();
196    }
197 
198    public WsdlOperation addNewOperation(BindingOperation operation)
199    {
200       WsdlOperation operationImpl = new WsdlOperation( this, getConfig().addNewOperation() );
201       operations.add( operationImpl );
202 
203       operationImpl.initFromBindingOperation( operation, false );
204       fireOperationAdded( operationImpl );
205       return operationImpl;
206    }
207 
208    public WsdlProject getProject()
209    {
210       return project;
211    }
212 
213    public void addEndpoint(String endpoint)
214    {
215       if( endpoint == null || endpoint.trim().length() == 0 ) return;
216       
217       endpoint = endpoint.trim();
218       String[] endpoints = getEndpoints();
219       
220       // dont add the same endpoint twice
221       if( Arrays.asList( endpoints ).contains( endpoint )) return;
222       
223       getConfig().getEndpoints().addNewEndpoint().setStringValue(endpoint);
224 		
225 		notifyPropertyChanged(ENDPOINT_PROPERTY, null, endpoint);
226    }
227    
228    public void changeEndpoint(String oldEndpoint, String newEndpoint)
229 	{
230    	if( oldEndpoint == null || oldEndpoint.trim().length() == 0 ) return;
231    	if( newEndpoint == null || newEndpoint.trim().length() == 0 ) return;
232    	
233    	EndpointsConfig endpoints = getConfig().getEndpoints();
234       List<EndpointConfig> endpointArray = endpoints.getEndpointList();
235       
236       String [] result = new String[endpointArray.size()];
237       
238       for( int c = 0; c < result.length; c++ )
239       {
240       	EndpointConfig endpoint = endpointArray.get( c );
241       	if( endpoint.getStringValue().equals( oldEndpoint ) )
242       	{
243       		endpoint.setStringValue( newEndpoint );
244          	notifyPropertyChanged(ENDPOINT_PROPERTY, oldEndpoint, newEndpoint);
245          	break;
246       	}
247       }
248 	}
249 
250 	public void removeEndpoint(String endpoint)
251 	{
252 		EndpointsConfig endpoints = getConfig().getEndpoints();
253       List<EndpointConfig> endpointArray = endpoints.getEndpointList();
254       
255       String [] result = new String[endpointArray.size()];
256       
257       for( int c = 0; c < result.length; c++ )
258       {
259       	EndpointConfig ep = endpointArray.get(c);
260       	if( ep.getStringValue().equals( endpoint ) )
261       	{
262       		endpoints.removeEndpoint( c );
263          	notifyPropertyChanged(ENDPOINT_PROPERTY, endpoint, null );
264          	break;
265       	}
266       }
267 	}
268 
269 	public void setDefinition( String wsdlUrl, boolean cache )
270    {
271       String old = getDefinition();
272       
273       getConfig().setDefinition( wsdlUrl );
274       
275       if( wsdlContext != null )
276       {
277       	wsdlContext.setDefinition( wsdlUrl, getConfig().getDefinitionCache() );
278       	wsdlContext.setSoapVersion( getSoapVersion() );
279       }
280       
281       notifyPropertyChanged( DEFINITION_PROPERTY, old, wsdlUrl );
282    }
283 
284 	public DefinitionCacheConfig cacheDefinition( WsdlLoader loader ) throws Exception
285 	{
286 		log.debug( "Caching definition for [" + loader.getBaseURI() + "]" );
287       if( getConfig().isSetDefinitionCache() )
288       	getConfig().unsetDefinitionCache();
289 
290 		DefinitionCacheConfig definitionCache = getConfig().addNewDefinitionCache();
291 		definitionCache.set( WsdlLoader.cacheWsdl( loader  ) );
292 		return definitionCache;
293 	}
294    
295    public String getDefinition()
296    {
297       return getConfig().isSetDefinition() ? getConfig().getDefinition() : null;
298    }
299    
300    public synchronized WsdlContext getWsdlContext()
301    {
302       if( wsdlContext == null )
303       {
304       	wsdlContext = new WsdlContext( getDefinition(), getSoapVersion(), getConfig().getDefinitionCache(), this );
305       }  
306       
307       return wsdlContext;
308    }
309    
310    /***
311     * Used by importer so we dont need to reload the context after importing..
312     * @param wsdlContext
313     */
314    
315    public void setWsdlContext( WsdlContext wsdlContext )
316    {
317    	this.wsdlContext = wsdlContext;
318    	this.wsdlContext.setSoapVersion( getSoapVersion() );
319    	
320    	if( !getConfig().isSetDefinitionCache() )
321 			getConfig().addNewDefinitionCache();
322    	
323    	if( wsdlContext.getCacheConfig() != null )
324    	{
325    		// use cache from context
326    		getConfig().setDefinitionCache( wsdlContext.getCacheConfig() );
327    	}
328    }
329 
330    public SoapMessageBuilder getMessageBuilder()
331    {
332       if( soapMessageBuilder == null )
333       {
334          try
335          {
336             soapMessageBuilder = new SoapMessageBuilder( this );
337          }
338          catch (Exception e)
339          {
340             e.printStackTrace();
341          }
342       }
343       return soapMessageBuilder;
344    }
345 
346    public void setSoapMessageBuilder(SoapMessageBuilder builder)
347    {
348       soapMessageBuilder = builder;
349       soapMessageBuilder.setInterface( this );
350    }
351 
352    public QName getBindingName()
353    {
354       return getConfig().getBindingName() == null ? null : QName.valueOf(getConfig().getBindingName());
355    }
356 
357    public void setBindingName(QName name)
358    {
359    	getConfig().setBindingName( name.toString() );
360    }
361    
362    public SoapVersion getSoapVersion()
363    {
364    	if( getConfig().getSoapVersion() == SoapVersionTypesConfig.X_1_2  )
365    		return SoapVersion.Soap12;
366    	
367    	return SoapVersion.Soap11;
368    }
369    
370    public void setSoapVersion( SoapVersion version )
371    {
372    	if( version == SoapVersion.Soap11 )
373    		getConfig().setSoapVersion( SoapVersionTypesConfig.X_1_1 );
374    	else if( version == SoapVersion.Soap12 )
375    		getConfig().setSoapVersion( SoapVersionTypesConfig.X_1_2 );
376    	else 
377    		throw new RuntimeException( "Unknown soapVersion [" + version + "], must be 1.1 or 1.2");
378    	
379    	getWsdlContext().setSoapVersion( version );
380    }
381 
382 	@SuppressWarnings("unchecked")
383 	public boolean updateDefinition(String url, boolean createRequests) throws Exception
384 	{
385 		WsdlContext newContext = null;
386 		
387 		if( getConfig().isSetDefinitionCache() )
388 			getConfig().unsetDefinitionCache();
389 		
390 		if( !getSettings().getBoolean( WsdlSettings.CACHE_WSDLS ) )
391 		{
392 			newContext = new WsdlContext( url, getSoapVersion(), null, null );
393 			newContext.load();
394 		}
395 		else
396 		{
397 			newContext = new WsdlContext( url, getSoapVersion(), null, this );	
398 		}
399 		
400 		Definition definition = newContext.getDefinition();
401 		Service service = null;
402 		Port port = null;
403 		Binding binding = null;
404 		
405 		// start by finding the old binding in the new definition
406 		Map serviceMap = definition.getAllServices();
407 		Iterator<String> i = serviceMap.keySet().iterator();
408 		while( i.hasNext() )
409 		{
410 			service = (Service) serviceMap.get( i.next() );
411 			Map portMap = service.getPorts();
412 			
413 			Iterator i2 = portMap.keySet().iterator();
414 			while( i2.hasNext() )
415 			{
416 				port = (Port) portMap.get( i2.next() );
417 				if( port.getBinding().getQName().equals( getBindingName() ))
418 				{
419 					binding = port.getBinding();
420 				}
421 			}
422 			
423 			if( binding != null ) break;
424 			service = null;
425 		}
426 		
427 		if( service == null && binding == null )
428 		{
429 			binding = definition.getBinding( getBindingName() );
430 		}
431 
432 		// missing matching binding, prompt for new one to use instead (will happen if binding has been renamed)
433 		if( binding == null )
434 		{
435 			Map bindings = definition.getAllBindings();
436 			
437 			Object retval = UISupport.prompt(  
438 					"Missing matching binding [" + getBindingName() + "] in definition, select new\nbinding to map to", 
439 					"Map Binding", bindings.keySet().toArray() );
440 			
441 			if( retval == null )
442 				return false;
443 			
444 			binding = (Binding) bindings.get( retval );
445 			setBindingName( binding.getQName() );
446 		}
447 		
448 		// update name
449 		if( getSettings().getBoolean( WsdlSettings.NAME_WITH_BINDING ))
450 			setName( binding.getQName().getLocalPart() );
451 		
452 		// prepare for transfer of operations/requests
453 		List<BindingOperation> newOperations = new ArrayList<BindingOperation>( binding.getBindingOperations() );
454 		Map<String,WsdlOperation> oldOperations = new HashMap<String,WsdlOperation>();
455 		for( int c = 0; c < operations.size(); c++ )
456 			oldOperations.put( operations.get( c ).getBindingOperationName(), operations.get( c ) );
457 		
458 		// clear existing from both collections
459 		for( int c = 0; c < newOperations.size(); c++ )
460 		{
461 			BindingOperation newOperation = newOperations.get( c );
462 			String bindingOperationName = newOperation.getName();
463 			if( oldOperations.containsKey( bindingOperationName) )
464 			{
465 				log.info( "Synchronizing existing operation [" + bindingOperationName + "]" );
466 				WsdlOperation wsdlOperation = oldOperations.get( bindingOperationName );
467 				wsdlOperation.initFromBindingOperation( newOperation, true );
468 				
469 				oldOperations.remove( bindingOperationName );
470 				newOperations.remove( c );
471 				c--;
472 			}
473 		}
474 		
475 		//	remove leftover operations
476 		i = oldOperations.keySet().iterator();
477 		while( i.hasNext())
478 		{
479 			String name = i.next();
480 			
481 			if( newOperations.size() > 0 )
482 		   {
483 				List<String> list = new ArrayList<String>();
484 				list.add( "none - delete operation" );
485 				for( int c = 0; c < newOperations.size(); c++ )
486 					list.add( newOperations.get( c ).getName() );
487 				
488 				String retval = (String) UISupport.prompt( 
489 						"Binding operation [" + name + "] not found in new interface, select new\nbinding operation to map to", 
490 						"Map Operation", list.toArray(), "none - delete operation" );
491 				
492 				if( retval == null )
493 				{
494 				   UISupport.showErrorMessage( "Aborting update of interface" );
495 				   return false;
496 				}
497 				
498 				int ix = list.indexOf( retval)-1;
499 				
500 				// delete operation?
501 				if( ix < 0 )
502 				{
503 					deleteOperation( name );
504 				}
505 				// change operation?
506 				else
507 				{
508 					BindingOperation newOperation = newOperations.get( ix );
509 					WsdlOperation wsdlOperation = oldOperations.get( name );
510 					wsdlOperation.initFromBindingOperation( newOperation, true );
511 					newOperations.remove( ix );
512 				}
513 
514 				oldOperations.remove( name );
515 		   }
516 			else 
517 			{
518 				deleteOperation( name );
519 				oldOperations.remove( name );
520 			}
521 			
522 			i = oldOperations.keySet().iterator();
523 		}
524 		
525 		wsdlContext = newContext;
526 		if( soapMessageBuilder != null )
527 			soapMessageBuilder.setWsdlContext( wsdlContext );
528 		
529 		// add leftover new operations
530 		if( newOperations.size() > 0 )
531 		{
532 			for( int c = 0; c < newOperations.size(); c++ )
533 			{
534 				BindingOperation newOperation = newOperations.get( c );
535 				WsdlOperation wsdlOperation = addNewOperation( newOperation );
536 				
537 				if( createRequests )
538 				{
539 					WsdlRequest request = wsdlOperation.addNewRequest( "Request 1");
540                try
541                {
542                   request.setRequestContent( wsdlOperation.createRequest( true ));
543                }
544                catch (Exception e)
545                {
546                   e.printStackTrace();
547                }
548 				}
549 			}
550 		}
551 		
552     	setDefinition( url, false );
553 
554 		if( port != null )
555 		{
556 			String endpoint = WsdlUtils.getSoapEndpoint( port );
557 	      if( endpoint != null )
558 	      {
559 	      	StringList list = new StringList( getEndpoints() );
560 	      	if( !list.contains( endpoint ))
561 	      	{
562 	      		if( UISupport.confirm( "Update existing requests with new endpoint\n[" + endpoint + "]", "Update Definition" ))
563 	      		{
564 	      			for( int c = 0; c < getOperationCount(); c++ )
565 	               {
566 	               	Operation operation = getOperationAt( c );
567 
568 	               	for( int ix = 0; ix < operation.getRequestCount(); ix++ )
569 	               	{
570 	               		operation.getRequestAt( ix ).setEndpoint( endpoint );
571 	               	}
572 	               }
573 	      		}
574 
575 	      		getConfig().getEndpoints().insertNewEndpoint( 0 ).setStringValue(endpoint);
576 		   		notifyPropertyChanged(ENDPOINT_PROPERTY, null, endpoint);
577 	      	}
578 	      }
579 		}
580 		
581 		return true;
582 	}
583 
584 	private void deleteOperation(String bindingOperationName)
585 	{
586 		for( int c = 0; c < operations.size(); c++ )
587 		{
588 			WsdlOperation wsdlOperation = operations.get( c );
589 			if( wsdlOperation.getBindingOperationName().equals( bindingOperationName ))
590 			{
591 				log.info( "deleting operation [" + bindingOperationName + "]" );
592 				
593 				// remove requests first (should this be done by some listener?)
594 				while( wsdlOperation.getRequestCount() > 0 )
595 					wsdlOperation.removeRequest( (WsdlRequest) wsdlOperation.getRequestAt( 0 ));
596 				
597 				operations.remove( c );
598 
599 				try
600 				{
601 					fireOperationRemoved( wsdlOperation );
602 				}
603 				finally
604 				{
605 					wsdlOperation.release();
606 					getConfig().removeOperation( c );
607 				}
608 				
609 				return;
610 			}
611 		}
612 	}
613 	
614 	public void fireOperationAdded( WsdlOperation operation )
615    {
616       InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
617       
618       for (int c = 0; c < a.length; c++ )
619       {
620          a[c].operationAdded( operation );
621       }
622    }
623 	
624 	public void fireOperationUpdated( WsdlOperation operation )
625    {
626       InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
627       
628       for (int c = 0; c < a.length; c++ )
629       {
630          a[c].operationUpdated( operation );
631       }
632    }
633    
634    public void fireOperationRemoved( WsdlOperation operation )
635    {
636    	InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
637       
638       for (int c = 0; c < a.length; c++ )
639       {
640          a[c].operationRemoved( operation );
641       }
642    }
643    
644    public void fireRequestAdded( WsdlRequest request )
645    {
646    	InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
647       
648       for (int c = 0; c < a.length; c++ )
649       {
650          a[c].requestAdded( request );
651       }
652    }
653    
654    public void fireRequestRemoved( WsdlRequest request )
655    {
656    	InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
657       
658       for (int c = 0; c < a.length; c++ )
659       {
660          a[c].requestRemoved( request );
661       }
662    }
663 
664 	public void addInterfaceListener(InterfaceListener listener)
665 	{
666 		listeners.add( listener );
667 	}
668 
669 	public void removeInterfaceListener(InterfaceListener listener)
670 	{
671 		listeners.remove( listener );
672 	}
673 
674 	/***
675 	 * Gets the endpoint url for the specified endpoint (which may be a label)
676 	 * 
677 	 * @param endpoint the endpoint to get for
678 	 * @return the endpoints url
679 	 */
680 	
681 	public String getEndpointURL(String endpoint)
682 	{
683 		List<EndpointConfig> endpointArray = getConfig().getEndpoints().getEndpointList();
684 		for( EndpointConfig endpointConfig : endpointArray )
685 		{
686 			if( endpointConfig.isSetLabel() && endpointConfig.getLabel().equals( endpoint ))
687 				return endpointConfig.getStringValue();
688 		}
689 		
690 		return endpoint;
691 	}
692 
693 	public WsdlOperation getOperationByName(String name)
694 	{
695 		return (WsdlOperation) getWsdlModelItemByName( operations, name );
696 	}
697 	
698 	public boolean isCached()
699 	{
700 		return getConfig().isSetDefinitionCache();
701 	}
702 
703 	public WsdlLoader createWsdlLoader()
704 	{
705 		return isCached() ? new CachedWsdlLoader( getConfig().getDefinitionCache() ) : 
706 			new UrlWsdlLoader( getDefinition() );
707 	}
708 	
709 	public void clearCache()
710 	{
711 		if( wsdlContext != null )
712 			wsdlContext.setDefinitionCache( null );
713 		
714 		if( getConfig().isSetDefinitionCache() )
715 			getConfig().unsetDefinitionCache();
716 	}
717 	
718 	public String getStyle()
719 	{
720 		if( wsdlContext == null || !wsdlContext.isLoaded() )
721 			return "<not loaded>";
722 		
723 		try
724 		{
725 			Binding binding = wsdlContext.getDefinition().getBinding( getBindingName() );
726 			if( binding == null )
727 				return "<missing binding>";
728 			
729 			if( WsdlUtils.isRpc( binding))
730 			{
731 				return STYLE_RPC;
732 			}
733 			else
734 			{
735 				return STYLE_DOCUMENT;
736 			}
737 		}
738 		catch (Exception e)
739 		{
740 			e.printStackTrace();
741 			return "<error>";
742 		}
743 	}
744 
745 	public void release()
746 	{
747 		super.release();
748 		
749 		for( WsdlOperation operation : operations )
750 			operation.release();
751 	}
752 
753 	public List<Operation> getOperations()
754 	{
755 		return new ArrayList<Operation>( operations );
756 	}
757 }