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