View Javadoc

1   /*
2    *  soapUI, copyright (C) 2006 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of the GNU Lesser General Public License as published by the Free Software Foundation; 
6    *  either version 2.1 of the License, or (at your option) any later version.
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 		// prepare for transfer of operations/requests
449 		List<BindingOperation> newOperations = new ArrayList<BindingOperation>( binding.getBindingOperations() );
450 		Map<String,WsdlOperation> oldOperations = new HashMap<String,WsdlOperation>();
451 		for( int c = 0; c < operations.size(); c++ )
452 			oldOperations.put( operations.get( c ).getBindingOperationName(), operations.get( c ) );
453 		
454 		// clear existing from both collections
455 		for( int c = 0; c < newOperations.size(); c++ )
456 		{
457 			BindingOperation newOperation = newOperations.get( c );
458 			String bindingOperationName = newOperation.getName();
459 			if( oldOperations.containsKey( bindingOperationName) )
460 			{
461 				log.info( "Synchronizing existing operation [" + bindingOperationName + "]" );
462 				WsdlOperation wsdlOperation = oldOperations.get( bindingOperationName );
463 				wsdlOperation.initFromBindingOperation( newOperation, true );
464 				
465 				oldOperations.remove( bindingOperationName );
466 				newOperations.remove( c );
467 				c--;
468 			}
469 		}
470 		
471 		//	remove leftover operations
472 		i = oldOperations.keySet().iterator();
473 		while( i.hasNext())
474 		{
475 			String name = i.next();
476 			
477 			if( newOperations.size() > 0 )
478 		   {
479 				List<String> list = new ArrayList<String>();
480 				list.add( "none - delete operation" );
481 				for( int c = 0; c < newOperations.size(); c++ )
482 					list.add( newOperations.get( c ).getName() );
483 				
484 				String retval = (String) UISupport.prompt( 
485 						"Binding operation [" + name + "] not found in new interface, select new\nbinding operation to map to", 
486 						"Map Operation", list.toArray(), "none - delete operation" );
487 				
488 				if( retval == null )
489 				{
490 				   UISupport.showErrorMessage( "Aborting update of interface" );
491 				   return false;
492 				}
493 				
494 				int ix = list.indexOf( retval)-1;
495 				
496 				// delete operation?
497 				if( ix < 0 )
498 				{
499 					deleteOperation( name );
500 				}
501 				// change operation?
502 				else
503 				{
504 					BindingOperation newOperation = newOperations.get( ix );
505 					WsdlOperation wsdlOperation = oldOperations.get( name );
506 					wsdlOperation.initFromBindingOperation( newOperation, true );
507 					newOperations.remove( ix );
508 				}
509 
510 				oldOperations.remove( name );
511 		   }
512 			else 
513 			{
514 				deleteOperation( name );
515 				oldOperations.remove( name );
516 			}
517 			
518 			i = oldOperations.keySet().iterator();
519 		}
520 		
521 		wsdlContext = newContext;
522 		if( soapMessageBuilder != null )
523 			soapMessageBuilder.setWsdlContext( wsdlContext );
524 		
525 		// add leftover new operations
526 		if( newOperations.size() > 0 )
527 		{
528 			for( int c = 0; c < newOperations.size(); c++ )
529 			{
530 				BindingOperation newOperation = newOperations.get( c );
531 				WsdlOperation wsdlOperation = addNewOperation( newOperation );
532 				
533 				if( createRequests )
534 				{
535 					WsdlRequest request = wsdlOperation.addNewRequest( "Request 1");
536                try
537                {
538                   request.setRequestContent( wsdlOperation.createRequest( true ));
539                }
540                catch (Exception e)
541                {
542                   e.printStackTrace();
543                }
544 				}
545 			}
546 		}
547 		
548     	setDefinition( url, false );
549 
550 		if( port != null )
551 		{
552 			String endpoint = WsdlUtils.getSoapEndpoint( port );
553 	      if( endpoint != null )
554 	      {
555 	      	StringList list = new StringList( getEndpoints() );
556 	      	if( !list.contains( endpoint ))
557 	      	{
558 	      		if( UISupport.confirm( "Update existing requests with new endpoint\n[" + endpoint + "]", "Update Definition" ))
559 	      		{
560 	      			for( int c = 0; c < getOperationCount(); c++ )
561 	               {
562 	               	Operation operation = getOperationAt( c );
563 
564 	               	for( int ix = 0; ix < operation.getRequestCount(); ix++ )
565 	               	{
566 	               		operation.getRequestAt( ix ).setEndpoint( endpoint );
567 	               	}
568 	               }
569 	      		}
570 
571 	      		getConfig().getEndpoints().insertNewEndpoint( 0 ).setStringValue(endpoint);
572 		   		notifyPropertyChanged(ENDPOINT_PROPERTY, null, endpoint);
573 	      	}
574 	      }
575 		}
576 		
577 		return true;
578 	}
579 
580 	private void deleteOperation(String bindingOperationName)
581 	{
582 		for( int c = 0; c < operations.size(); c++ )
583 		{
584 			WsdlOperation wsdlOperation = operations.get( c );
585 			if( wsdlOperation.getBindingOperationName().equals( bindingOperationName ))
586 			{
587 				log.info( "deleting operation [" + bindingOperationName + "]" );
588 				
589 				// remove requests first (should this be done by some listener?)
590 				while( wsdlOperation.getRequestCount() > 0 )
591 					wsdlOperation.removeRequest( (WsdlRequest) wsdlOperation.getRequestAt( 0 ));
592 				
593 				operations.remove( c );
594 
595 				try
596 				{
597 					fireOperationRemoved( wsdlOperation );
598 				}
599 				finally
600 				{
601 					wsdlOperation.release();
602 					getConfig().removeOperation( c );
603 				}
604 				
605 				return;
606 			}
607 		}
608 	}
609 	
610 	public void fireOperationAdded( WsdlOperation operation )
611    {
612       InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
613       
614       for (int c = 0; c < a.length; c++ )
615       {
616          a[c].operationAdded( operation );
617       }
618    }
619 	
620 	public void fireOperationUpdated( WsdlOperation operation )
621    {
622       InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
623       
624       for (int c = 0; c < a.length; c++ )
625       {
626          a[c].operationUpdated( operation );
627       }
628    }
629    
630    public void fireOperationRemoved( WsdlOperation operation )
631    {
632    	InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
633       
634       for (int c = 0; c < a.length; c++ )
635       {
636          a[c].operationRemoved( operation );
637       }
638    }
639    
640    public void fireRequestAdded( WsdlRequest request )
641    {
642    	InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
643       
644       for (int c = 0; c < a.length; c++ )
645       {
646          a[c].requestAdded( request );
647       }
648    }
649    
650    public void fireRequestRemoved( WsdlRequest request )
651    {
652    	InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
653       
654       for (int c = 0; c < a.length; c++ )
655       {
656          a[c].requestRemoved( request );
657       }
658    }
659 
660 	public void addInterfaceListener(InterfaceListener listener)
661 	{
662 		listeners.add( listener );
663 	}
664 
665 	public void removeInterfaceListener(InterfaceListener listener)
666 	{
667 		listeners.remove( listener );
668 	}
669 
670 	/***
671 	 * Gets the endpoint url for the specified endpoint (which may be a label)
672 	 * 
673 	 * @param endpoint the endpoint to get for
674 	 * @return the endpoints url
675 	 */
676 	
677 	public String getEndpointURL(String endpoint)
678 	{
679 		List<EndpointConfig> endpointArray = getConfig().getEndpoints().getEndpointList();
680 		for( EndpointConfig endpointConfig : endpointArray )
681 		{
682 			if( endpointConfig.isSetLabel() && endpointConfig.getLabel().equals( endpoint ))
683 				return endpointConfig.getStringValue();
684 		}
685 		
686 		return endpoint;
687 	}
688 
689 	public WsdlOperation getOperationByName(String name)
690 	{
691 		return (WsdlOperation) getWsdlModelItemByName( operations, name );
692 	}
693 	
694 	public boolean isCached()
695 	{
696 		return getConfig().isSetDefinitionCache();
697 	}
698 
699 	public WsdlLoader createWsdlLoader()
700 	{
701 		return isCached() ? new CachedWsdlLoader( getConfig().getDefinitionCache() ) : 
702 			new UrlWsdlLoader( getDefinition() );
703 	}
704 	
705 	public void clearCache()
706 	{
707 		if( wsdlContext != null )
708 			wsdlContext.setDefinitionCache( null );
709 		
710 		if( getConfig().isSetDefinitionCache() )
711 			getConfig().unsetDefinitionCache();
712 	}
713 	
714 	public String getStyle()
715 	{
716 		if( wsdlContext == null || !wsdlContext.isLoaded() )
717 			return "<not loaded>";
718 		
719 		try
720 		{
721 			Binding binding = wsdlContext.getDefinition().getBinding( getBindingName() );
722 			if( binding == null )
723 				return "<missing binding>";
724 			
725 			if( WsdlUtils.isRpc( binding))
726 			{
727 				return STYLE_RPC;
728 			}
729 			else
730 			{
731 				return STYLE_DOCUMENT;
732 			}
733 		}
734 		catch (Exception e)
735 		{
736 			e.printStackTrace();
737 			return "<error>";
738 		}
739 	}
740 
741 	public void release()
742 	{
743 		super.release();
744 		
745 		for( WsdlOperation operation : operations )
746 			operation.release();
747 	}
748 
749 	public List<Operation> getOperations()
750 	{
751 		return new ArrayList<Operation>( operations );
752 	}
753 }