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.HashMap;
17 import java.util.List;
18 import java.util.Map;
19
20 import javax.swing.ImageIcon;
21 import javax.wsdl.Binding;
22 import javax.wsdl.BindingOperation;
23 import javax.wsdl.BindingOutput;
24 import javax.wsdl.Definition;
25 import javax.wsdl.extensions.mime.MIMEContent;
26 import javax.wsdl.extensions.mime.MIMEMultipartRelated;
27 import javax.wsdl.extensions.mime.MIMEPart;
28 import javax.xml.namespace.QName;
29
30 import org.apache.xmlbeans.SchemaType;
31
32 import com.eviware.soapui.config.CallConfig;
33 import com.eviware.soapui.config.OperationConfig;
34 import com.eviware.soapui.config.PartsConfig.Part;
35 import com.eviware.soapui.impl.wsdl.actions.operation.AddToMockServiceAction;
36 import com.eviware.soapui.impl.wsdl.actions.operation.NewRequestAction;
37 import com.eviware.soapui.impl.wsdl.actions.operation.RelabelOperationAction;
38 import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
39 import com.eviware.soapui.impl.wsdl.support.HelpUrls;
40 import com.eviware.soapui.impl.wsdl.support.soap.SoapMessageBuilder;
41 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlContext;
42 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils;
43 import com.eviware.soapui.model.iface.MessagePart;
44 import com.eviware.soapui.model.iface.Operation;
45 import com.eviware.soapui.model.iface.Request;
46 import com.eviware.soapui.model.iface.MessagePart.FaultPart;
47 import com.eviware.soapui.support.UISupport;
48 import com.eviware.soapui.support.action.ActionSupport;
49
50 /***
51 * WSDL implementation of Operation, maps to a WSDL BindingOperation
52 *
53 * @author Ole.Matzura
54 */
55
56 public class WsdlOperation extends AbstractWsdlModelItem<OperationConfig> implements Operation
57 {
58 public static final String STYLE_DOCUMENT = "Document";
59 public static final String STYLE_RPC = "RPC";
60 private List<WsdlRequest> requests = new ArrayList<WsdlRequest>();
61 private WsdlInterface iface;
62 private ImageIcon oneWayIcon;
63
64 public WsdlOperation( WsdlInterface iface, OperationConfig operationConfig )
65 {
66 super( operationConfig, iface, "/operation.gif" );
67 this.iface = iface;
68
69 if( operationConfig.isSetIsOneWay())
70 {
71 operationConfig.setIsOneWay( false );
72 }
73
74 List<CallConfig> requestConfigs = getConfig().getCallList();
75 for (CallConfig config : requestConfigs)
76 {
77 requests.add( new WsdlRequest( this, config));
78 }
79
80 addAction( new AddToMockServiceAction( this ));
81
82 addAction( ActionSupport.SEPARATOR_ACTION );
83 addAction( new NewRequestAction( this ));
84 addAction( new RelabelOperationAction( this ));
85 addAction( ActionSupport.SEPARATOR_ACTION );
86 addAction( new ShowOnlineHelpAction( HelpUrls.OPERATION_HELP_URL ));
87
88 oneWayIcon = UISupport.createImageIcon( "/onewayoperation.gif" );
89 }
90
91 public String getAction()
92 {
93 return getConfig().getAction();
94 }
95
96 public WsdlRequest getRequestAt(int index)
97 {
98 return requests.get( index );
99 }
100
101 public WsdlRequest getRequestByName(String requestName)
102 {
103 return (WsdlRequest) getWsdlModelItemByName( requests, requestName );
104 }
105
106 public int getRequestCount()
107 {
108 return requests.size();
109 }
110
111 public ImageIcon getIcon()
112 {
113 if( isOneWay() )
114 return oneWayIcon;
115 else
116 return super.getIcon();
117 }
118
119 public WsdlRequest addNewRequest( String name )
120 {
121 WsdlRequest requestImpl = new WsdlRequest( this, getConfig().addNewCall() );
122 requestImpl.setName( name );
123 requests.add( requestImpl );
124 ((WsdlInterface)getInterface()).fireRequestAdded( requestImpl );
125 return requestImpl;
126 }
127
128 public WsdlInterface getInterface()
129 {
130 return iface;
131 }
132
133 public void setAction(String soapAction)
134 {
135 String old = getAction();
136 getConfig().setAction( soapAction );
137 notifyPropertyChanged( ACTION_PROPERTY, old, soapAction );
138 }
139
140 public String createRequest( boolean buildOptional )
141 {
142 if( iface.getBindingName() == null )
143 {
144 UISupport.showErrorMessage( "Missing binding name, please try to refresh " +
145 "Interface\nfor request generation to work correctly" );
146 return null;
147 }
148
149 if( getBindingOperationName() == null )
150 {
151 UISupport.showErrorMessage( "Missing bindingOperation name, please try to refresh " +
152 "Interface\nfor request generation to work correctly" );
153 return null;
154 }
155
156 try
157 {
158 SoapMessageBuilder builder = (SoapMessageBuilder) iface.getMessageBuilder();
159 BindingOperation bindingOperation = findBindingOperation( iface.getWsdlContext().getDefinition() );
160
161 if( bindingOperation == null )
162 {
163 UISupport.showErrorMessage( "Failed to find bindingOperation, please try to refresh " +
164 "Interface\nfor request generation to work correctly" );
165 return null;
166 }
167
168 return builder.buildSoapRequest( bindingOperation, buildOptional );
169 }
170 catch (Exception e)
171 {
172 e.printStackTrace();
173 return null;
174 }
175 }
176
177 public String createResponse( boolean buildOptional )
178 {
179 if( iface.getBindingName() == null )
180 {
181 UISupport.showErrorMessage( "Missing binding name, please try to refresh " +
182 "Interface\nfor request generation to work correctly" );
183 return null;
184 }
185
186 if( getBindingOperationName() == null )
187 {
188 UISupport.showErrorMessage( "Missing bindingOperation name, please try to refresh " +
189 "Interface\nfor request generation to work correctly" );
190 return null;
191 }
192
193 try
194 {
195 SoapMessageBuilder builder = (SoapMessageBuilder) iface.getMessageBuilder();
196 BindingOperation bindingOperation = findBindingOperation( iface.getWsdlContext().getDefinition() );
197
198 if( bindingOperation == null )
199 {
200 UISupport.showErrorMessage( "Failed to find bindingOperation, please try to refresh " +
201 "Interface\nfor request generation to work correctly" );
202 return null;
203 }
204
205 return builder.buildSoapResponse( bindingOperation, buildOptional );
206 }
207 catch (Exception e)
208 {
209 e.printStackTrace();
210 return null;
211 }
212 }
213
214 public BindingOperation findBindingOperation(Definition definition)
215 {
216 Binding binding = definition.getBinding( iface.getBindingName() );
217 if( binding == null )
218 return null;
219
220 String inputName = getInputName();
221 String outputName = getOutputName();
222
223 if( inputName == null )
224 inputName = ":none";
225
226 if( outputName == null )
227 outputName = ":none";
228
229 BindingOperation result = binding.getBindingOperation( getConfig().getBindingOperationName(), inputName, outputName );
230
231 if( result == null && (inputName.equals( ":none" ) || outputName.equals( ":none" )))
232 {
233
234 result = binding.getBindingOperation( getConfig().getBindingOperationName(),
235 inputName.equals( ":none" ) ? null : inputName, outputName.equals( ":none" ) ? null : outputName );
236 }
237 return result;
238 }
239
240 public void removeRequest( WsdlRequest request )
241 {
242 int ix = requests.indexOf( request );
243 requests.remove( ix );
244
245 try
246 {
247 ((WsdlInterface)getInterface()).fireRequestRemoved( request );
248 }
249 finally
250 {
251 request.release();
252 getConfig().removeCall( ix );
253 }
254 }
255
256 public String getBindingOperationName()
257 {
258 return getConfig().getBindingOperationName();
259 }
260
261 public void setBindingOperationName( String name )
262 {
263 getConfig().setBindingOperationName( name );
264 }
265
266 public void setInputName( String name )
267 {
268 getConfig().setInputName( name );
269 }
270
271 public String getInputName()
272 {
273 String inputName = getConfig().getInputName();
274 return inputName == null || inputName.trim().length() == 0 ? null : inputName;
275 }
276
277 public void setOutputName( String name )
278 {
279 if( name == null )
280 {
281 if( getConfig().isSetOutputName() )
282 getConfig().unsetOutputName();
283 }
284 else
285 getConfig().setOutputName( name );
286 }
287
288 public String getOutputName()
289 {
290 String outputName = getConfig().getOutputName();
291 return outputName == null || outputName.trim().length() == 0 ? null : outputName;
292 }
293
294 public void setOneWay( boolean isOneWay )
295 {
296 getConfig().setIsOneWay( isOneWay );
297 }
298
299 public boolean isOneWay()
300 {
301 return getConfig().getIsOneWay();
302 }
303
304 public void initFromBindingOperation(BindingOperation operation, boolean notifyUpdate )
305 {
306 setAction( WsdlUtils.getSoapAction( operation ));
307 setName( operation.getOperation().getName() );
308 setBindingOperationName( operation.getName() );
309 setInputName( operation.getBindingInput().getName() );
310
311 BindingOutput bindingOutput = operation.getBindingOutput();
312
313
314 if( bindingOutput != null )
315 setOutputName( bindingOutput.getName() );
316 else
317 setOutputName( null );
318
319 setOneWay( bindingOutput == null );
320
321 initAttachments(operation);
322
323 if( notifyUpdate )
324 {
325 iface.fireOperationUpdated( this );
326 }
327 }
328
329 private void initAttachments(BindingOperation operation)
330 {
331 if( getConfig().isSetRequestParts() )
332 getConfig().unsetRequestParts();
333
334 if( getConfig().isSetResponseParts() )
335 getConfig().unsetResponseParts();
336
337 BindingOutput bindingOutput = operation.getBindingOutput();
338
339 if( bindingOutput != null )
340 {
341 MIMEMultipartRelated multipartOutput = (MIMEMultipartRelated) WsdlUtils.getExtensiblityElement(
342 bindingOutput.getExtensibilityElements(), MIMEMultipartRelated.class );
343
344 getConfig().setReceivesAttachments( multipartOutput != null );
345 }
346
347 MIMEMultipartRelated multipartInput = (MIMEMultipartRelated) WsdlUtils.getExtensiblityElement(
348 operation.getBindingInput().getExtensibilityElements(), MIMEMultipartRelated.class );
349
350 getConfig().setSendsAttachments( multipartInput != null );
351 if( multipartInput != null )
352 {
353 List<MIMEPart> parts = multipartInput.getMIMEParts();
354 Map<String,Part> partMap = new HashMap<String,Part>();
355
356 for( int c = 0; c < parts.size(); c++ )
357 {
358 List<MIMEContent> contentParts = WsdlUtils.getExtensiblityElements( parts.get(c).getExtensibilityElements(), MIMEContent.class );
359
360 for( MIMEContent content : contentParts )
361 {
362 Part part = partMap.get( content.getPart());
363 if( part != null )
364 {
365 if( !part.getContentTypeList().contains( content.getType() ))
366 part.addContentType( content.getType() );
367 }
368 else
369 {
370 if( !getConfig().isSetRequestParts() )
371 getConfig().addNewRequestParts();
372
373 Part requestPart = getConfig().getRequestParts().addNewPart();
374 requestPart.addContentType( content.getType() );
375 requestPart.setName( content.getPart() );
376
377 partMap.put( requestPart.getName(), requestPart );
378 }
379 }
380 }
381 }
382 }
383
384 public boolean getReceivesAttachments()
385 {
386 return getConfig().getReceivesAttachments();
387 }
388
389 public boolean getSendsAttachments()
390 {
391 return getConfig().getSendsAttachments();
392 }
393
394 public QName getRequestBodyElementQName() throws Exception
395 {
396 WsdlInterface iface = (WsdlInterface) getInterface();
397
398 Definition definition = iface.getWsdlContext().getDefinition();
399 BindingOperation bindingOperation = findBindingOperation( definition );
400 if( WsdlUtils.isRpc( definition, bindingOperation))
401 {
402 String ns = WsdlUtils.getSoapBodyNamespace( bindingOperation.getBindingInput().getExtensibilityElements() );
403 if( ns == null )
404 {
405 ns = definition.getTargetNamespace();
406 }
407
408 return new QName( ns, bindingOperation.getName() );
409 }
410 else
411 {
412 List<javax.wsdl.Part> parts = bindingOperation.getOperation().getInput().getMessage().getOrderedParts( null );
413 if( parts == null || parts.isEmpty() )
414 return null;
415
416 javax.wsdl.Part part = parts.get( 0 );
417
418 if( part.getElementName() != null )
419 {
420 return part.getElementName();
421 }
422 else
423 {
424 return new QName( definition.getTargetNamespace(), part.getName() );
425 }
426 }
427 }
428
429 public QName getResponseBodyElementQName() throws Exception
430 {
431 if( isOneWay() )
432 return null;
433
434 WsdlInterface iface = (WsdlInterface) getInterface();
435
436 Definition definition = iface.getWsdlContext().getDefinition();
437 BindingOperation bindingOperation = findBindingOperation( definition );
438 if( WsdlUtils.isRpc( definition, bindingOperation))
439 {
440 String ns = WsdlUtils.getSoapBodyNamespace( bindingOperation.getBindingOutput().getExtensibilityElements() );
441 if( ns == null )
442 {
443 ns = definition.getTargetNamespace();
444 }
445
446 return new QName( ns, bindingOperation.getName() + "Response" );
447 }
448 else
449 {
450 List<javax.wsdl.Part> parts = bindingOperation.getOperation().getOutput().getMessage().getOrderedParts( null );
451 if( parts == null || parts.isEmpty() )
452 return null;
453
454 javax.wsdl.Part part = parts.get( 0 );
455
456 if( part.getElementName() != null )
457 {
458 return part.getElementName();
459 }
460 else
461 {
462 return new QName( definition.getTargetNamespace(), part.getName() );
463 }
464 }
465 }
466
467 public String getStyle()
468 {
469 WsdlContext wsdlContext = iface.getWsdlContext();
470 if( !wsdlContext.isLoaded() )
471 return "<not loaded>";
472
473 try
474 {
475 Definition definition = wsdlContext.getDefinition();
476 BindingOperation bindingOperation = findBindingOperation( definition);
477
478 if( bindingOperation == null )
479 return "<missing bindingOperation>";
480
481 if( WsdlUtils.isRpc( definition, bindingOperation ))
482 {
483 return WsdlOperation.STYLE_RPC;
484 }
485 else
486 {
487 return WsdlOperation.STYLE_DOCUMENT;
488 }
489 }
490 catch (Exception e)
491 {
492 e.printStackTrace();
493 return "<error>";
494 }
495 }
496
497 public void release()
498 {
499 super.release();
500
501 for( WsdlRequest request : requests )
502 request.release();
503 }
504
505 public BindingOperation getBindingOperation()
506 {
507 try
508 {
509 return findBindingOperation( ((WsdlInterface)getInterface()).getWsdlContext().getDefinition() );
510 }
511 catch( Exception e )
512 {
513 e.printStackTrace();
514 return null;
515 }
516 }
517
518 public List<Request> getRequests()
519 {
520 return new ArrayList<Request>( requests );
521 }
522
523 public MessagePart [] getFaultParts()
524 {
525 BindingOperation bindingOperation = getBindingOperation();
526 Map bindingFaults = bindingOperation.getBindingFaults();
527
528 List<MessagePart> result = new ArrayList<MessagePart>();
529 for( Object key : bindingFaults.keySet() )
530 {
531 result.add( new WsdlFaultPart( (String)key ));
532 }
533
534 return result.toArray( new MessagePart[result.size()] );
535 }
536
537 private class WsdlFaultPart extends FaultPart
538 {
539 private final String name;
540
541 public WsdlFaultPart( String name )
542 {
543 this.name = name;
544 }
545
546 @Override
547 public javax.wsdl.Part[] getWsdlParts()
548 {
549 return WsdlUtils.getFaultParts( getBindingOperation(), name );
550 }
551
552 @Override
553 public QName getPartElement()
554 {
555 return null;
556 }
557
558 public String getDescription()
559 {
560 return null;
561 }
562
563 public String getName()
564 {
565 return name;
566 }
567
568 @Override
569 public SchemaType getSchemaType()
570 {
571 return null;
572 }}
573 }