1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.rest.panels.request;
14
15 import com.eviware.soapui.impl.rest.RestRequest;
16 import com.eviware.soapui.impl.rest.RestResource;
17 import com.eviware.soapui.impl.rest.support.RestUtils;
18 import com.eviware.soapui.impl.rest.support.XmlBeansRestParamsTestPropertyHolder;
19 import com.eviware.soapui.impl.support.AbstractHttpRequest.RequestMethod;
20 import com.eviware.soapui.impl.support.components.ModelItemXmlEditor;
21 import com.eviware.soapui.impl.support.panels.AbstractHttpRequestDesktopPanel;
22 import com.eviware.soapui.impl.wsdl.WsdlSubmitContext;
23 import com.eviware.soapui.impl.wsdl.submit.transports.http.HttpResponse;
24 import com.eviware.soapui.impl.wsdl.teststeps.RestTestRequest;
25 import com.eviware.soapui.model.ModelItem;
26 import com.eviware.soapui.model.iface.Request.SubmitException;
27 import com.eviware.soapui.model.iface.Submit;
28 import com.eviware.soapui.model.support.TestPropertyListenerAdapter;
29 import com.eviware.soapui.model.testsuite.TestProperty;
30 import com.eviware.soapui.support.DocumentListenerAdapter;
31 import com.eviware.soapui.support.UISupport;
32 import com.eviware.soapui.support.components.JUndoableTextField;
33 import com.eviware.soapui.support.components.JXToolBar;
34 import com.eviware.soapui.support.editor.xml.support.AbstractXmlDocument;
35 import com.eviware.soapui.support.swing.ModelItemListCellRenderer;
36
37 import javax.swing.*;
38 import javax.swing.text.Document;
39 import java.awt.*;
40 import java.awt.event.ItemEvent;
41 import java.awt.event.ItemListener;
42 import java.beans.PropertyChangeEvent;
43 import java.beans.PropertyChangeListener;
44
45 public abstract class AbstractRestRequestDesktopPanel<T extends ModelItem, T2 extends RestRequest>
46 extends AbstractHttpRequestDesktopPanel<T, T2>
47 {
48 private boolean updatingRequest;
49 private JComboBox methodCombo;
50 private JUndoableTextField pathTextField;
51 private JComboBox acceptCombo;
52 private JLabel pathLabel;
53 private boolean updating;
54 private AbstractRestRequestDesktopPanel<T, T2>.InternalTestPropertyListener testPropertyListener = new AbstractRestRequestDesktopPanel.InternalTestPropertyListener();
55 private AbstractRestRequestDesktopPanel<T, T2>.RestParamPropertyChangeListener restParamPropertyChangeListener = new AbstractRestRequestDesktopPanel.RestParamPropertyChangeListener();
56 private JComboBox pathCombo;
57
58 public AbstractRestRequestDesktopPanel( T modelItem, T2 requestItem )
59 {
60 super( modelItem, requestItem );
61
62 if( requestItem.getResource() != null )
63 {
64 requestItem.getResource().addPropertyChangeListener( this );
65 }
66
67 requestItem.addTestPropertyListener( testPropertyListener );
68
69 for( TestProperty param : requestItem.getParams().getProperties().values() )
70 {
71 ( (XmlBeansRestParamsTestPropertyHolder.RestParamProperty) param ).addPropertyChangeListener( restParamPropertyChangeListener );
72 }
73 }
74
75 public void propertyChange( PropertyChangeEvent evt )
76 {
77 updateFullPathLabel();
78
79 if( evt.getPropertyName().equals( "method" ) && !updatingRequest )
80 {
81 methodCombo.setSelectedItem( evt.getNewValue() );
82 }
83 else if( evt.getPropertyName().equals( "accept" ) && !updatingRequest )
84 {
85 acceptCombo.setSelectedItem( evt.getNewValue() );
86 }
87 else if( evt.getPropertyName().equals( "responseMediaTypes" ) && !updatingRequest )
88 {
89 Object item = acceptCombo.getSelectedItem();
90 acceptCombo.setModel( new DefaultComboBoxModel( (Object[]) evt.getNewValue() ) );
91 acceptCombo.setSelectedItem( item );
92 }
93 else if( evt.getPropertyName().equals( "path" ) &&
94 ( getRequest().getResource() == null || getRequest().getResource() == evt.getSource() ) )
95 {
96 if( pathLabel != null )
97 {
98 updateFullPathLabel();
99 }
100
101 if( !updating && pathTextField != null )
102 {
103 updating = true;
104 pathTextField.setText( (String) evt.getNewValue() );
105 pathTextField.setToolTipText( pathTextField.getText() );
106 updating = false;
107 }
108 }
109
110 super.propertyChange( evt );
111 }
112
113 @Override
114 protected ModelItemXmlEditor<?, ?> buildRequestEditor()
115 {
116 return new RestRequestMessageEditor( getRequest() );
117 }
118
119 @Override
120 protected ModelItemXmlEditor<?, ?> buildResponseEditor()
121 {
122 return new RestResponseMessageEditor( getRequest() );
123 }
124
125 @Override
126 protected Submit doSubmit() throws SubmitException
127 {
128 return getRequest().submit( new WsdlSubmitContext( getModelItem() ), true );
129 }
130
131 @Override
132 protected String getHelpUrl()
133 {
134 return null;
135 }
136
137 @Override
138 protected void insertButtons( JXToolBar toolbar )
139 {
140 if( getRequest().getResource() == null )
141 {
142 addToolbarComponents( toolbar );
143 }
144 }
145
146 protected JComponent buildEndpointComponent()
147 {
148 return getRequest().getResource() == null ? null : super.buildEndpointComponent();
149 }
150
151 @Override
152 protected JComponent buildToolbar()
153 {
154 if( getRequest().getResource() != null )
155 {
156 JPanel panel = new JPanel( new BorderLayout() );
157 panel.add( super.buildToolbar(), BorderLayout.NORTH );
158
159 JXToolBar toolbar = UISupport.createToolbar();
160 addToolbarComponents( toolbar );
161
162 panel.add( toolbar, BorderLayout.SOUTH );
163 return panel;
164 }
165 else
166 {
167 return super.buildToolbar();
168 }
169 }
170
171 protected void addToolbarComponents( JXToolBar toolbar )
172 {
173 toolbar.addSeparator();
174 methodCombo = new JComboBox( new Object[]{RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT,
175 RequestMethod.DELETE, RequestMethod.HEAD} );
176
177 methodCombo.setSelectedItem( getRequest().getMethod() );
178 methodCombo.setToolTipText( "Set desired HTTP method" );
179 methodCombo.addItemListener( new ItemListener()
180 {
181 public void itemStateChanged( ItemEvent e )
182 {
183 updatingRequest = true;
184 getRequest().setMethod( (RequestMethod) methodCombo.getSelectedItem() );
185 updatingRequest = false;
186 }
187 } );
188
189 toolbar.addLabeledFixed( "Method", methodCombo );
190 toolbar.addSeparator();
191
192 if( getRequest().getResource() != null )
193 {
194 acceptCombo = new JComboBox( getRequest().getResponseMediaTypes() );
195 acceptCombo.setEditable( true );
196 acceptCombo.setToolTipText( "Sets accepted encoding(s) for response" );
197 acceptCombo.setSelectedItem( getRequest().getAccept() );
198 acceptCombo.addItemListener( new ItemListener()
199 {
200 public void itemStateChanged( ItemEvent e )
201 {
202 updatingRequest = true;
203 getRequest().setAccept( String.valueOf( acceptCombo.getSelectedItem() ) );
204 updatingRequest = false;
205 }
206 } );
207
208 toolbar.addLabeledFixed( "Accept", acceptCombo );
209 toolbar.addSeparator();
210
211 if( getRequest() instanceof RestTestRequest )
212 {
213 pathCombo = new JComboBox( new PathComboBoxModel() );
214 pathCombo.setRenderer( new ModelItemListCellRenderer() );
215 pathCombo.setPreferredSize( new Dimension( 200, 20 ) );
216 pathCombo.setSelectedItem( getRequest().getResource().getPath() );
217 pathCombo.addItemListener( new ItemListener()
218 {
219 public void itemStateChanged( ItemEvent e )
220 {
221 if( updating )
222 return;
223
224 updating = true;
225 getRequest().getResource().setPath( String.valueOf( pathCombo.getSelectedItem() ) );
226 updating = false;
227 }
228 } );
229
230 toolbar.addLabeledFixed( "Resource:", pathCombo );
231 toolbar.addSeparator();
232 }
233 else
234 {
235 toolbar.add( new JLabel( "Full Path: " ));
236 }
237
238 pathLabel = new JLabel();
239 updateFullPathLabel();
240
241 toolbar.add( pathLabel );
242 }
243 else
244 {
245 pathTextField = new JUndoableTextField();
246 pathTextField.setPreferredSize( new Dimension( 300, 20 ) );
247 pathTextField.setText( getRequest().getPath() );
248 pathTextField.setToolTipText( pathTextField.getText() );
249 pathTextField.getDocument().addDocumentListener( new DocumentListenerAdapter()
250 {
251 @Override
252 public void update( Document document )
253 {
254 getRequest().setPath( pathTextField.getText() );
255 }
256 } );
257
258 toolbar.addLabeledFixed( "Request URL:", pathTextField );
259 }
260
261 toolbar.addSeparator();
262 }
263
264 protected boolean release()
265 {
266 if( getRequest().getResource() != null )
267 {
268 getRequest().getResource().removePropertyChangeListener( this );
269 }
270
271 getRequest().removeTestPropertyListener( testPropertyListener );
272
273 for( TestProperty param : getRequest().getParams().getProperties().values() )
274 {
275 ( (XmlBeansRestParamsTestPropertyHolder.RestParamProperty) param ).removePropertyChangeListener( restParamPropertyChangeListener );
276 }
277
278 return super.release();
279 }
280
281 public class RestRequestMessageEditor extends
282 AbstractHttpRequestDesktopPanel<?, ?>.AbstractHttpRequestMessageEditor<RestRequestDocument>
283 {
284 public RestRequestMessageEditor( RestRequest modelItem )
285 {
286 super( new RestRequestDocument( modelItem ) );
287 }
288 }
289
290 public class RestResponseMessageEditor extends
291 AbstractHttpRequestDesktopPanel<?, ?>.AbstractHttpResponseMessageEditor<RestResponseDocument>
292 {
293 public RestResponseMessageEditor( RestRequest modelItem )
294 {
295 super( new RestResponseDocument( modelItem ) );
296 }
297 }
298
299 public class RestRequestDocument extends AbstractXmlDocument implements PropertyChangeListener
300 {
301 private final RestRequest modelItem;
302 private boolean updating;
303
304 public RestRequestDocument( RestRequest modelItem )
305 {
306 this.modelItem = modelItem;
307
308 modelItem.addPropertyChangeListener( this );
309 }
310
311 public RestRequest getRequest()
312 {
313 return modelItem;
314 }
315
316 public String getXml()
317 {
318 return getRequest().getRequestContent();
319 }
320
321 public void setXml( String xml )
322 {
323 if( !updating )
324 {
325 updating = true;
326 getRequest().setRequestContent( xml );
327 updating = false;
328 }
329 }
330
331 public void propertyChange( PropertyChangeEvent evt )
332 {
333 if( evt.getPropertyName().equals( RestRequest.REQUEST_PROPERTY ) && !updating )
334 {
335 updating = true;
336 fireXmlChanged( (String) evt.getOldValue(), (String) evt.getNewValue() );
337 updating = false;
338 }
339 }
340 }
341
342 public class RestResponseDocument extends AbstractXmlDocument implements PropertyChangeListener
343 {
344 private final RestRequest modelItem;
345
346 public RestResponseDocument( RestRequest modelItem )
347 {
348 this.modelItem = modelItem;
349
350 modelItem.addPropertyChangeListener( RestRequest.RESPONSE_PROPERTY, this );
351 }
352
353 public RestRequest getRequest()
354 {
355 return modelItem;
356 }
357
358 public String getXml()
359 {
360 return modelItem.getResponseContentAsXml();
361 }
362
363 public void setXml( String xml )
364 {
365 HttpResponse response = getRequest().getResponse();
366 if( response != null )
367 response.setResponseContent( xml );
368 }
369
370 public void propertyChange( PropertyChangeEvent evt )
371 {
372 fireXmlChanged( evt.getOldValue() == null ? null : ( (HttpResponse) evt.getOldValue() ).getContentAsString(),
373 getXml() );
374 }
375 }
376
377 private class InternalTestPropertyListener extends TestPropertyListenerAdapter
378 {
379 @Override
380 public void propertyValueChanged( String name, String oldValue, String newValue )
381 {
382 updateFullPathLabel();
383 }
384
385 @Override
386 public void propertyAdded( String name )
387 {
388 updateFullPathLabel();
389
390 getRequest().getParams().getProperty( name ).addPropertyChangeListener( restParamPropertyChangeListener );
391 }
392
393 @Override
394 public void propertyRemoved( String name )
395 {
396 updateFullPathLabel();
397 }
398
399 @Override
400 public void propertyRenamed( String oldName, String newName )
401 {
402 updateFullPathLabel();
403 }
404 }
405
406 private void updateFullPathLabel()
407 {
408 if( pathLabel != null && getRequest().getResource() != null )
409 {
410 String text = RestUtils.expandPath( getRequest().getResource().getFullPath(), getRequest().getParams(), getRequest() );
411 pathLabel.setText( "[" + text + "]" );
412 pathLabel.setToolTipText( text );
413 }
414 }
415
416 private class RestParamPropertyChangeListener implements PropertyChangeListener
417 {
418 public void propertyChange( PropertyChangeEvent evt )
419 {
420 updateFullPathLabel();
421 }
422 }
423
424 private class PathComboBoxModel extends AbstractListModel implements ComboBoxModel
425 {
426 public int getSize()
427 {
428 return getRequest().getResource().getService().getAllResources().size();
429 }
430
431 public Object getElementAt( int index )
432 {
433 return getRequest().getResource().getService().getAllResources().get( index );
434 }
435
436 public void setSelectedItem( Object anItem )
437 {
438 ( (RestTestRequest) getRequest() ).setResource( (RestResource) anItem );
439 }
440
441 public Object getSelectedItem()
442 {
443 return getRequest().getResource();
444 }
445 }
446 }