1
2
3
4
5
6
7
8
9
10
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.swing.ImageIcon;
25 import javax.swing.JOptionPane;
26 import javax.wsdl.Binding;
27 import javax.wsdl.BindingOperation;
28 import javax.wsdl.Definition;
29 import javax.wsdl.Port;
30 import javax.wsdl.Service;
31 import javax.wsdl.extensions.soap.SOAPAddress;
32 import javax.xml.namespace.QName;
33
34 import org.apache.log4j.Logger;
35
36 import com.eviware.soapui.SoapUI;
37 import com.eviware.soapui.config.EndpointConfig;
38 import com.eviware.soapui.config.EndpointsConfig;
39 import com.eviware.soapui.config.InterfaceConfig;
40 import com.eviware.soapui.config.OperationConfig;
41 import com.eviware.soapui.impl.wsdl.actions.iface.InterfaceEndpointsAction;
42 import com.eviware.soapui.impl.wsdl.actions.iface.RemoveInterfaceAction;
43 import com.eviware.soapui.impl.wsdl.actions.iface.UpdateInterfaceAction;
44 import com.eviware.soapui.impl.wsdl.panels.iface.WsdlInterfacePanelBuilder;
45 import com.eviware.soapui.impl.wsdl.support.SoapRequestBuilder;
46 import com.eviware.soapui.impl.wsdl.support.WsdlContext;
47 import com.eviware.soapui.impl.wsdl.support.WsdlUtils;
48 import com.eviware.soapui.model.PanelBuilder;
49 import com.eviware.soapui.model.iface.Interface;
50 import com.eviware.soapui.model.iface.InterfaceListener;
51 import com.eviware.soapui.model.iface.Operation;
52 import com.eviware.soapui.model.iface.RequestBuilder;
53 import com.eviware.soapui.model.project.Project;
54 import com.eviware.soapui.model.tree.SoapUITreeNode;
55 import com.eviware.soapui.model.tree.nodes.InterfaceTreeNode;
56 import com.eviware.soapui.support.UISupport;
57
58 /***
59 * WSDL implementation of Interface, maps to a WSDL Binding
60 *
61 * @author Ole.Matzura
62 */
63
64 public class WsdlInterface extends AbstractWsdlModelItem implements Interface
65 {
66 private final static Logger log = Logger.getLogger( WsdlInterface.class );
67
68 private InterfaceConfig interfaceConfig;
69 private List<WsdlOperation> operations = new ArrayList<WsdlOperation>();
70 private final WsdlProject project;
71 private SoapRequestBuilder soapRequestBuilder;
72 private WsdlInterfacePanelBuilder wsdlInterfacePanelBuilder;
73 private WsdlContext wsdlContext;
74 private ImageIcon interfaceIcon;
75 private Set<InterfaceListener> listeners = new HashSet<InterfaceListener>();
76
77 public WsdlInterface( WsdlProject project, InterfaceConfig interfaceConfig )
78 {
79 this.project = project;
80 this.interfaceConfig = interfaceConfig;
81
82 if( interfaceConfig.getEndpoints() == null )
83 interfaceConfig.addNewEndpoints();
84
85 OperationConfig [] operationConfigs = interfaceConfig.getOperationArray();
86 for (int i = 0; i < operationConfigs.length; i++)
87 {
88 operations.add( new WsdlOperation( this, operationConfigs[i] ));
89 }
90
91 addAction( new InterfaceEndpointsAction( this ) );
92 addAction( new UpdateInterfaceAction( this ) );
93 addAction( new RemoveInterfaceAction( this ) );
94
95 wsdlInterfacePanelBuilder = new WsdlInterfacePanelBuilder( this );
96 interfaceIcon = SoapUI.createImageIcon("/interface.gif");
97 }
98
99 public PanelBuilder getPanelBuilder()
100 {
101 return wsdlInterfacePanelBuilder;
102 }
103
104 public String[] getEndpoints()
105 {
106 EndpointsConfig endpoints = interfaceConfig.getEndpoints();
107 EndpointConfig[] endpointArray = endpoints.getEndpointArray();
108
109 String [] result = new String[endpointArray.length];
110
111 for( int c = 0; c < endpointArray.length; c++ )
112 {
113 EndpointConfig endpoint = endpointArray[c];
114 if( endpoint.isSetLabel() )
115 result[c] = endpoint.getLabel();
116 else
117 result[c] = endpoint.getStringValue();
118 }
119
120 return result;
121 }
122
123 public Operation getOperationAt(int index)
124 {
125 return operations.get(index);
126 }
127
128 public int getOperationCount()
129 {
130 return operations.size();
131 }
132
133 public String getName()
134 {
135 try
136 {
137 return interfaceConfig.getName();
138 }
139 catch( Exception e )
140 {
141 return null;
142 }
143 }
144
145 public void setName( String name )
146 {
147 String oldName = getName();
148 interfaceConfig.setName( name );
149 notifyPropertyChanged( NAME_PROPERTY, oldName, name );
150 }
151
152 public InterfaceConfig getInterfaceConfig()
153 {
154 return interfaceConfig;
155 }
156
157 public WsdlOperation addNewOperation()
158 {
159 WsdlOperation operationImpl = new WsdlOperation( this, interfaceConfig.addNewOperation() );
160 operations.add( operationImpl );
161 return operationImpl;
162 }
163
164 public Project getProject()
165 {
166 return project;
167 }
168
169 public void addEndpoint(String endpoint)
170 {
171 if( endpoint == null || endpoint.trim().length() == 0 ) return;
172
173 String[] endpoints = getEndpoints();
174
175
176 if( Arrays.asList( endpoints ).contains( endpoint )) return;
177
178 interfaceConfig.getEndpoints().addNewEndpoint().setStringValue(endpoint);
179
180 notifyPropertyChanged(ENDPOINT_PROPERTY, null, endpoint);
181 }
182
183 public void changeEndpoint(String oldEndpoint, String newEndpoint)
184 {
185 EndpointsConfig endpoints = interfaceConfig.getEndpoints();
186 EndpointConfig[] endpointArray = endpoints.getEndpointArray();
187
188 String [] result = new String[endpointArray.length];
189
190 for( int c = 0; c < endpointArray.length; c++ )
191 {
192 EndpointConfig endpoint = endpointArray[c];
193 if( endpoint.getStringValue().equals( oldEndpoint ) )
194 {
195 endpoint.setStringValue( newEndpoint );
196 notifyPropertyChanged(ENDPOINT_PROPERTY, oldEndpoint, newEndpoint);
197 break;
198 }
199 }
200 }
201
202 public void removeEndpoint(String endpoint)
203 {
204 EndpointsConfig endpoints = interfaceConfig.getEndpoints();
205 EndpointConfig[] endpointArray = endpoints.getEndpointArray();
206
207 String [] result = new String[endpointArray.length];
208
209 for( int c = 0; c < endpointArray.length; c++ )
210 {
211 EndpointConfig ep = endpointArray[c];
212 if( ep.getStringValue().equals( endpoint ) )
213 {
214 endpoints.removeEndpoint( c );
215 notifyPropertyChanged(ENDPOINT_PROPERTY, endpoint, null );
216 break;
217 }
218 }
219 }
220
221 public void setDefinition( String wsdlUrl )
222 {
223 String old = getDefinition();
224 if( old != null && wsdlUrl.equals(old)) return;
225
226 interfaceConfig.setDefinition( wsdlUrl );
227 if( wsdlContext != null )
228 wsdlContext.setDefinition( wsdlUrl );
229
230 notifyPropertyChanged( DEFINITION_PROPERTY, old, wsdlUrl );
231 }
232
233 public String getDefinition()
234 {
235 try
236 {
237 return interfaceConfig.isSetDefinition() ? interfaceConfig.getDefinition() : null;
238 }
239 catch( Exception e )
240 {
241 return null;
242 }
243 }
244
245 public WsdlContext getWsdlContext()
246 {
247 if( wsdlContext == null )
248 wsdlContext = new WsdlContext( getDefinition() );
249
250 return wsdlContext;
251 }
252
253 public RequestBuilder getRequestBuilder()
254 {
255 if( soapRequestBuilder == null )
256 {
257 try
258 {
259 soapRequestBuilder = new SoapRequestBuilder( this );
260 }
261 catch (Exception e)
262 {
263 e.printStackTrace();
264 }
265 }
266 return soapRequestBuilder;
267 }
268
269 public void setSoapRequestBuilder(SoapRequestBuilder builder)
270 {
271 this.soapRequestBuilder = builder;
272 }
273
274 public QName getBindingName()
275 {
276 return interfaceConfig.getBindingName() == null ? null : QName.valueOf(interfaceConfig.getBindingName());
277 }
278
279 public void setBindingName(QName name)
280 {
281 interfaceConfig.setBindingName( name.toString() );
282 }
283
284 public ImageIcon getIcon()
285 {
286 return interfaceIcon;
287 }
288
289 protected SoapUITreeNode createTreeNode()
290 {
291 return new InterfaceTreeNode( this );
292 }
293
294 public void updateDefinition(String url) throws Exception
295 {
296 WsdlContext newContext = new WsdlContext( url );
297
298 Definition definition = newContext.getDefinition();
299 Service service = null;
300 Port port = null;
301 Binding binding = null;
302
303
304 Map serviceMap = definition.getServices();
305 Iterator<String> i = serviceMap.keySet().iterator();
306 while( i.hasNext() )
307 {
308 service = (Service) serviceMap.get( i.next() );
309 Map portMap = service.getPorts();
310
311 Iterator i2 = portMap.keySet().iterator();
312 while( i2.hasNext() )
313 {
314 port = (Port) portMap.get( i2.next() );
315 if( port.getBinding().getQName().equals( getBindingName() ))
316 {
317 binding = port.getBinding();
318 }
319 }
320
321 if( binding != null ) break;
322 service = null;
323 }
324
325 if( service == null && binding == null )
326 {
327 binding = definition.getBinding( getBindingName() );
328 }
329
330
331 if( binding == null )
332 {
333 Map bindings = definition.getBindings();
334
335 Object retval = JOptionPane.showInputDialog( SoapUI.getInstance().getFrame(),
336 "Missing matching binding [" + getBindingName() + "] in definition, select new\nbinding to map to",
337 "Map Binding", JOptionPane.QUESTION_MESSAGE, null, bindings.keySet().toArray(), null );
338
339 if( retval == null )
340 return;
341
342 binding = (Binding) bindings.get( retval );
343 setBindingName( binding.getQName() );
344 }
345
346
347 List<BindingOperation> newOperations = new ArrayList<BindingOperation>( binding.getBindingOperations() );
348 Map<String,WsdlOperation> oldOperations = new HashMap<String,WsdlOperation>();
349 for( int c = 0; c < operations.size(); c++ )
350 oldOperations.put( operations.get( c ).getBindingOperationName(), operations.get( c ) );
351
352
353 for( int c = 0; c < newOperations.size(); c++ )
354 {
355 BindingOperation newOperation = newOperations.get( c );
356 String bindingOperationName = newOperation.getName();
357 if( oldOperations.containsKey( bindingOperationName) )
358 {
359 log.info( "Synchronizing existing operation [" + bindingOperationName + "]" );
360 WsdlOperation wsdlOperation = oldOperations.get( bindingOperationName );
361 wsdlOperation.setAction( WsdlUtils.getSoapAction( newOperation));
362 wsdlOperation.setName( newOperation.getOperation().getName() );
363
364 oldOperations.remove( bindingOperationName );
365 newOperations.remove( c );
366 c--;
367 }
368 }
369
370
371 i = oldOperations.keySet().iterator();
372 while( i.hasNext())
373 {
374 String name = i.next();
375
376 if( newOperations.size() > 0 )
377 {
378 List<String> list = new ArrayList<String>();
379 list.add( "none - delete operation" );
380 for( int c = 0; c < newOperations.size(); c++ )
381 list.add( newOperations.get( c ).getName() );
382
383 String retval = (String) JOptionPane.showInputDialog( SoapUI.getInstance().getFrame(),
384 "Binding operation [" + name + "] not found in new interface, select new\nbinding operation to map to",
385 "Map Operation", JOptionPane.QUESTION_MESSAGE, null, list.toArray(), "none - delete operation" );
386
387 if( retval == null )
388 {
389 UISupport.showErrorMessage( "Aborting update of interface" );
390 return;
391 }
392
393 int ix = list.indexOf( retval)-1;
394
395
396 if( ix < 0 )
397 {
398 deleteOperation( name );
399 }
400
401 else
402 {
403 BindingOperation newOperation = newOperations.get( ix );
404 WsdlOperation wsdlOperation = oldOperations.get( name );
405 wsdlOperation.setAction( WsdlUtils.getSoapAction( newOperation));
406 wsdlOperation.setName( newOperation.getOperation().getName() );
407 wsdlOperation.setBindingOperationName( newOperation.getName() );
408
409 newOperations.remove( ix );
410 }
411
412 oldOperations.remove( name );
413 }
414 else
415 {
416 deleteOperation( name );
417 oldOperations.remove( name );
418 }
419
420 i = oldOperations.keySet().iterator();
421 }
422
423
424 for( int c = 0; c < newOperations.size(); c++ )
425 {
426 BindingOperation newOperation = newOperations.get( c );
427 WsdlOperation wsdlOperation = addNewOperation();
428 wsdlOperation.setAction( WsdlUtils.getSoapAction( newOperation));
429 wsdlOperation.setName( newOperation.getOperation().getName() );
430 wsdlOperation.setBindingOperationName( newOperation.getName() );
431
432 notifyOperationAdded( wsdlOperation );
433 }
434
435 wsdlContext = newContext;
436 if( soapRequestBuilder != null )
437 soapRequestBuilder.setWsdlContext( wsdlContext );
438
439 setDefinition( url );
440
441 if( port != null )
442 {
443 SOAPAddress address = (SOAPAddress) WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(), SOAPAddress.class );
444 if( address != null )
445 addEndpoint( address.getLocationURI() );
446 }
447 }
448
449 private void deleteOperation(String bindingOperationName)
450 {
451 for( int c = 0; c < operations.size(); c++ )
452 {
453 WsdlOperation wsdlOperation = operations.get( c );
454 if( wsdlOperation.getBindingOperationName().equals( bindingOperationName ))
455 {
456 log.info( "deleting operation [" + bindingOperationName + "]" );
457 notifyOperationRemoved( wsdlOperation );
458 wsdlOperation.release();
459
460 operations.remove( c );
461 interfaceConfig.removeOperation( c );
462
463 return;
464 }
465 }
466 }
467
468 public void notifyOperationAdded( WsdlOperation operation )
469 {
470 InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
471
472 for (int c = 0; c < a.length; c++ )
473 {
474 a[c].operationAdded( operation );
475 }
476 }
477
478 public void notifyOperationRemoved( WsdlOperation operation )
479 {
480 InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
481
482 for (int c = 0; c < a.length; c++ )
483 {
484 a[c].operationRemoved( operation );
485 }
486 }
487
488 public void notifyRequestAdded( WsdlRequest request )
489 {
490 InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
491
492 for (int c = 0; c < a.length; c++ )
493 {
494 a[c].requestAdded( request );
495 }
496 }
497
498 public void notifyRequestRemoved( WsdlRequest request )
499 {
500 InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
501
502 for (int c = 0; c < a.length; c++ )
503 {
504 a[c].requestRemoved( request );
505 }
506 }
507
508 public void addInterfaceListener(InterfaceListener listener)
509 {
510 listeners.add( listener );
511 }
512
513 public void removeInterfaceListener(InterfaceListener listener)
514 {
515 listeners.remove( listener );
516 }
517
518 /***
519 * Gets the endpoint url for the specified endpoint (which may be a label)
520 *
521 * @param endpoint the endpoint to get for
522 * @return the endpoints url
523 */
524
525 public String getEndpointURL(String endpoint)
526 {
527 EndpointConfig[] endpointArray = interfaceConfig.getEndpoints().getEndpointArray();
528 for( int c = 0; c < endpointArray.length; c++ )
529 {
530 EndpointConfig endpointConfig = endpointArray[c];
531 if( endpointConfig.isSetLabel() && endpointConfig.getLabel().equals( endpoint ))
532 return endpointConfig.getStringValue();
533 }
534
535 return endpoint;
536 }
537 }