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.InterfaceConfig;
38 import com.eviware.soapui.config.OperationConfig;
39 import com.eviware.soapui.impl.wsdl.actions.iface.InterfaceEndpointsAction;
40 import com.eviware.soapui.impl.wsdl.actions.iface.RemoveInterfaceAction;
41 import com.eviware.soapui.impl.wsdl.actions.iface.UpdateInterfaceAction;
42 import com.eviware.soapui.impl.wsdl.panels.iface.WsdlInterfacePanelBuilder;
43 import com.eviware.soapui.impl.wsdl.support.SoapRequestBuilder;
44 import com.eviware.soapui.impl.wsdl.support.WsdlContext;
45 import com.eviware.soapui.impl.wsdl.support.WsdlUtils;
46 import com.eviware.soapui.model.PanelBuilder;
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.model.iface.RequestBuilder;
51 import com.eviware.soapui.model.project.Project;
52 import com.eviware.soapui.model.tree.SoapUITreeNode;
53 import com.eviware.soapui.model.tree.nodes.InterfaceTreeNode;
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 implements Interface
62 {
63 private final static Logger log = Logger.getLogger( WsdlInterface.class );
64
65 private InterfaceConfig interfaceConfig;
66 private List<WsdlOperation> operations = new ArrayList<WsdlOperation>();
67 private final WsdlProject project;
68 private SoapRequestBuilder soapRequestBuilder;
69 private WsdlInterfacePanelBuilder wsdlInterfacePanelBuilder;
70 private WsdlContext wsdlContext;
71 private ImageIcon interfaceIcon;
72 private Set<InterfaceListener> listeners = new HashSet<InterfaceListener>();
73
74 public WsdlInterface( WsdlProject project, InterfaceConfig interfaceConfig )
75 {
76 this.project = project;
77 this.interfaceConfig = interfaceConfig;
78
79 if( interfaceConfig.getEndpoints() == null )
80 interfaceConfig.addNewEndpoints();
81
82 OperationConfig [] operationConfigs = interfaceConfig.getOperationArray();
83 for (int i = 0; i < operationConfigs.length; i++)
84 {
85 operations.add( new WsdlOperation( this, operationConfigs[i] ));
86 }
87
88 addAction( new InterfaceEndpointsAction( this ) );
89 addAction( new UpdateInterfaceAction( this ) );
90 addAction( new RemoveInterfaceAction( this ) );
91
92 wsdlInterfacePanelBuilder = new WsdlInterfacePanelBuilder( this );
93 interfaceIcon = SoapUI.createImageIcon("/interface.gif");
94 }
95
96 public PanelBuilder getPanelBuilder()
97 {
98 return wsdlInterfacePanelBuilder;
99 }
100
101 public String[] getEndpoints()
102 {
103 return interfaceConfig.getEndpoints().getEndpointArray();
104 }
105
106 public Operation getOperationAt(int index)
107 {
108 return operations.get(index);
109 }
110
111 public int getOperationCount()
112 {
113 return operations.size();
114 }
115
116 public String getName()
117 {
118 try
119 {
120 return interfaceConfig.getName();
121 }
122 catch( Exception e )
123 {
124 return null;
125 }
126 }
127
128 public void setName( String name )
129 {
130 String oldName = getName();
131 interfaceConfig.setName( name );
132 notifyPropertyChanged( NAME_PROPERTY, oldName, name );
133 }
134
135 public InterfaceConfig getInterfaceConfig()
136 {
137 return interfaceConfig;
138 }
139
140 public WsdlOperation addNewOperation()
141 {
142 WsdlOperation operationImpl = new WsdlOperation( this, interfaceConfig.addNewOperation() );
143 operations.add( operationImpl );
144 return operationImpl;
145 }
146
147 public Project getProject()
148 {
149 return project;
150 }
151
152 public void addEndpoint(String endpoint)
153 {
154 if( endpoint == null || endpoint.trim().length() == 0 ) return;
155
156 List l = Arrays.asList( interfaceConfig.getEndpoints().getEndpointArray() );
157 if( !l.contains( endpoint ))
158 {
159 String [] endpoints = getEndpoints();
160 interfaceConfig.getEndpoints().addEndpoint( endpoint );
161 notifyPropertyChanged( ENDPOINTS_PROPERTY, endpoints, getEndpoints() );
162 }
163 }
164
165 public void setDefinition( String wsdlUrl )
166 {
167 String old = getDefinition();
168 if( old != null && wsdlUrl.equals(old)) return;
169
170 interfaceConfig.setDefinition( wsdlUrl );
171 if( wsdlContext != null )
172 wsdlContext.setDefinition( wsdlUrl );
173
174 notifyPropertyChanged( DEFINITION_PROPERTY, old, wsdlUrl );
175 }
176
177 public String getDefinition()
178 {
179 try
180 {
181 return interfaceConfig.isSetDefinition() ? interfaceConfig.getDefinition() : null;
182 }
183 catch( Exception e )
184 {
185 return null;
186 }
187 }
188
189 public WsdlContext getWsdlContext()
190 {
191 if( wsdlContext == null )
192 wsdlContext = new WsdlContext( getDefinition() );
193
194 return wsdlContext;
195 }
196
197 public void clearEndpoints()
198 {
199 String [] endpoints = getEndpoints();
200 interfaceConfig.getEndpoints().setEndpointArray( new String[] {} );
201 notifyPropertyChanged( ENDPOINTS_PROPERTY, endpoints, getEndpoints() );
202 }
203
204 public RequestBuilder getRequestBuilder()
205 {
206 if( soapRequestBuilder == null )
207 {
208 try
209 {
210 soapRequestBuilder = new SoapRequestBuilder( this );
211 }
212 catch (Exception e)
213 {
214 e.printStackTrace();
215 }
216 }
217 return soapRequestBuilder;
218 }
219
220 public void setSoapRequestBuilder(SoapRequestBuilder builder)
221 {
222 this.soapRequestBuilder = builder;
223 }
224
225 public QName getBindingName()
226 {
227 return interfaceConfig.getBindingName() == null ? null : QName.valueOf(interfaceConfig.getBindingName());
228 }
229
230 public void setBindingName(QName name)
231 {
232 interfaceConfig.setBindingName( name.toString() );
233 }
234
235 public ImageIcon getIcon()
236 {
237 return interfaceIcon;
238 }
239
240 protected SoapUITreeNode createTreeNode()
241 {
242 return new InterfaceTreeNode( this );
243 }
244
245 public void updateDefinition(String url) throws Exception
246 {
247 WsdlContext newContext = new WsdlContext( url );
248
249 Definition definition = newContext.getDefinition();
250 Service service = null;
251 Port port = null;
252 Binding binding = null;
253
254 Map serviceMap = definition.getServices();
255 Iterator<String> i = serviceMap.keySet().iterator();
256 while( i.hasNext() )
257 {
258 service = (Service) serviceMap.get( i.next() );
259 Map portMap = service.getPorts();
260
261 Iterator i2 = portMap.keySet().iterator();
262 while( i2.hasNext() )
263 {
264 port = (Port) portMap.get( i2.next() );
265 if( port.getBinding().getQName().equals( getBindingName() ))
266 {
267 binding = port.getBinding();
268 }
269 }
270
271 if( binding != null ) break;
272 service = null;
273 }
274
275 if( service == null && binding == null )
276 {
277 binding = definition.getBinding( getBindingName() );
278 }
279
280 if( binding == null )
281 {
282 JOptionPane.showMessageDialog( SoapUI.getInstance().getFrame(), "Missing matching binding [" +
283 getBindingName() + "] in definition" );
284 return;
285 }
286
287 List<BindingOperation> newOperations = new ArrayList<BindingOperation>( binding.getBindingOperations() );
288 Map<String,WsdlOperation> oldOperations = new HashMap<String,WsdlOperation>();
289 for( int c = 0; c < operations.size(); c++ )
290 oldOperations.put( operations.get( c ).getBindingOperationName(), operations.get( c ) );
291
292
293 for( int c = 0; c < newOperations.size(); c++ )
294 {
295 BindingOperation newOperation = newOperations.get( c );
296 String bindingOperationName = newOperation.getName();
297 if( oldOperations.containsKey( bindingOperationName) )
298 {
299 log.info( "Synchronizing existing operation [" + bindingOperationName + "]" );
300 WsdlOperation wsdlOperation = oldOperations.get( bindingOperationName );
301 wsdlOperation.setAction( WsdlUtils.getSoapAction( newOperation));
302 wsdlOperation.setName( newOperation.getOperation().getName() );
303
304 oldOperations.remove( bindingOperationName );
305 newOperations.remove( c );
306 c--;
307 }
308 }
309
310
311 i = oldOperations.keySet().iterator();
312 while( i.hasNext())
313 {
314 String name = i.next();
315
316 if( newOperations.size() > 0 )
317 {
318 List<String> list = new ArrayList<String>();
319 list.add( "none - delete operation" );
320 for( int c = 0; c < newOperations.size(); c++ )
321 list.add( newOperations.get( c ).getName() );
322
323 String retval = (String) JOptionPane.showInputDialog( SoapUI.getInstance().getFrame(),
324 "Binding operation [" + name + "] not found in new interface, select new\nbinding operation to map to",
325 "Map Operation", JOptionPane.QUESTION_MESSAGE, null, list.toArray(), "none - delete operation" );
326
327 int ix = list.indexOf( retval)-1;
328
329
330 if( ix < 0 )
331 {
332 deleteOperation( name );
333 }
334
335 else
336 {
337 BindingOperation newOperation = newOperations.get( ix );
338 WsdlOperation wsdlOperation = oldOperations.get( name );
339 wsdlOperation.setAction( WsdlUtils.getSoapAction( newOperation));
340 wsdlOperation.setName( newOperation.getOperation().getName() );
341 wsdlOperation.setBindingOperationName( newOperation.getName() );
342
343 newOperations.remove( ix );
344 oldOperations.remove( name );
345 }
346 }
347 else
348 {
349 deleteOperation( name );
350 oldOperations.remove( name );
351 }
352
353 i = oldOperations.keySet().iterator();
354 }
355
356
357 for( int c = 0; c < newOperations.size(); c++ )
358 {
359 BindingOperation newOperation = newOperations.get( c );
360 WsdlOperation wsdlOperation = addNewOperation();
361 wsdlOperation.setAction( WsdlUtils.getSoapAction( newOperation));
362 wsdlOperation.setName( newOperation.getOperation().getName() );
363 wsdlOperation.setBindingOperationName( newOperation.getName() );
364
365 notifyOperationAdded( wsdlOperation );
366 }
367
368 wsdlContext = newContext;
369 if( soapRequestBuilder != null )
370 soapRequestBuilder.setWsdlContext( wsdlContext );
371
372 setDefinition( url );
373
374 if( port != null )
375 {
376 SOAPAddress address = (SOAPAddress) WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(), SOAPAddress.class );
377 if( address != null )
378 addEndpoint( address.getLocationURI() );
379 }
380 }
381
382 private void deleteOperation(String bindingOperationName)
383 {
384 for( int c = 0; c < operations.size(); c++ )
385 {
386 WsdlOperation wsdlOperation = operations.get( c );
387 if( wsdlOperation.getBindingOperationName().equals( bindingOperationName ))
388 {
389 log.info( "deleting operation [" + bindingOperationName + "]" );
390 notifyOperationRemoved( wsdlOperation );
391 wsdlOperation.release();
392
393 operations.remove( c );
394 interfaceConfig.removeOperation( c );
395
396 return;
397 }
398 }
399 }
400
401 public void notifyOperationAdded( WsdlOperation operation )
402 {
403 InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
404
405 for (int c = 0; c < a.length; c++ )
406 {
407 a[c].operationAdded( operation );
408 }
409 }
410
411 public void notifyOperationRemoved( WsdlOperation operation )
412 {
413 InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
414
415 for (int c = 0; c < a.length; c++ )
416 {
417 a[c].operationRemoved( operation );
418 }
419 }
420
421 public void notifyRequestAdded( WsdlRequest request )
422 {
423 InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
424
425 for (int c = 0; c < a.length; c++ )
426 {
427 a[c].requestAdded( request );
428 }
429 }
430
431 public void notifyRequestRemoved( WsdlRequest request )
432 {
433 InterfaceListener[] a = listeners.toArray( new InterfaceListener[listeners.size()] );
434
435 for (int c = 0; c < a.length; c++ )
436 {
437 a[c].requestRemoved( request );
438 }
439 }
440
441 public void addInterfaceListener(InterfaceListener listener)
442 {
443 listeners.add( listener );
444 }
445
446 public void removeInterfaceListener(InterfaceListener listener)
447 {
448 listeners.remove( listener );
449 }
450 }