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.RestRepresentation;
16 import com.eviware.soapui.impl.rest.RestRepresentation.Type;
17 import com.eviware.soapui.impl.rest.RestRequest;
18 import com.eviware.soapui.impl.support.AbstractHttpRequest.RequestMethod;
19 import com.eviware.soapui.impl.support.HttpUtils;
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.model.ModelItem;
25 import com.eviware.soapui.model.iface.Request.SubmitException;
26 import com.eviware.soapui.model.iface.Submit;
27 import com.eviware.soapui.model.iface.SubmitContext;
28 import com.eviware.soapui.support.DocumentListenerAdapter;
29 import com.eviware.soapui.support.UISupport;
30 import com.eviware.soapui.support.components.JUndoableTextField;
31 import com.eviware.soapui.support.components.JXToolBar;
32 import com.eviware.soapui.support.editor.xml.support.AbstractXmlDocument;
33
34 import javax.swing.*;
35 import javax.swing.text.Document;
36 import java.awt.*;
37 import java.awt.event.ItemEvent;
38 import java.awt.event.ItemListener;
39 import java.beans.PropertyChangeEvent;
40 import java.beans.PropertyChangeListener;
41 import java.util.ArrayList;
42 import java.util.Arrays;
43 import java.util.List;
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
55
56 public AbstractRestRequestDesktopPanel( T modelItem, T2 requestItem )
57 {
58 super( modelItem, requestItem );
59
60 if( requestItem.getResource() != null )
61 requestItem.getResource().addPropertyChangeListener( this );
62 }
63
64 public void propertyChange( PropertyChangeEvent evt )
65 {
66 if( evt.getPropertyName().equals( "method" ) && !updatingRequest )
67 {
68 methodCombo.setSelectedItem( evt.getNewValue() );
69 }
70 else if( evt.getPropertyName().equals( "accept" ) && !updatingRequest )
71 {
72 acceptCombo.setSelectedItem( evt.getNewValue() );
73 }
74 else if( evt.getPropertyName().equals( "responseMediaTypes" ) && !updatingRequest )
75 {
76 Object item = acceptCombo.getSelectedItem();
77 acceptCombo.setModel( new DefaultComboBoxModel( ( Object[] ) evt.getNewValue() ) );
78 acceptCombo.setSelectedItem( item );
79 }
80 else if( evt.getPropertyName().equals( "path" ) &&
81 ( getRequest().getResource() == null || getRequest().getResource() == evt.getSource() ) )
82 {
83 if( pathLabel != null )
84 {
85 pathLabel.setText( getRequest().getResource().getFullPath() );
86 }
87
88 if( !updating )
89 {
90 updating = true;
91 pathTextField.setText( ( String ) evt.getNewValue() );
92 updating = false;
93 }
94 }
95
96 super.propertyChange( evt );
97 }
98
99 @Override
100 protected ModelItemXmlEditor<?, ?> buildRequestEditor()
101 {
102 return new RestRequestMessageEditor( getRequest() );
103 }
104
105 @Override
106 protected ModelItemXmlEditor<?, ?> buildResponseEditor()
107 {
108 return new RestResponseMessageEditor( getRequest() );
109 }
110
111 @Override
112 protected Submit doSubmit() throws SubmitException
113 {
114 return getRequest().submit( new WsdlSubmitContext( getModelItem() ), true );
115 }
116
117 @Override
118 public void afterSubmit( Submit submit, SubmitContext context )
119 {
120 super.afterSubmit( submit, context );
121
122 HttpResponse response = getRequest().getResponse();
123 if( response != null )
124 {
125 if( HttpUtils.isErrorStatus( response.getStatusCode() ) )
126 {
127 extractRepresentation( response, RestRepresentation.Type.FAULT );
128 }
129 else
130 {
131 extractRepresentation( response, RestRepresentation.Type.RESPONSE );
132 }
133 }
134 }
135
136 @SuppressWarnings( "unchecked" )
137 private void extractRepresentation( HttpResponse response, Type type )
138 {
139 RestRepresentation[] representations = getRequest().getRepresentations( type, null );
140 int c = 0;
141 for( ; c < representations.length; c++ )
142 {
143 if( representations[c].getMediaType().equals( response.getContentType() ) )
144 {
145 List status = representations[c].getStatus();
146 if( status == null || !status.contains( response.getStatusCode() ) )
147 {
148 status = status == null ? new ArrayList<Integer>() : new ArrayList<Integer>( status );
149 status.add( response.getStatusCode() );
150 representations[c].setStatus( status );
151 }
152 break;
153 }
154 }
155
156 if( c == representations.length )
157 {
158 RestRepresentation representation = getRequest().addNewRepresentation( type );
159 representation.setMediaType( response.getContentType() );
160 representation.setStatus( Arrays.asList( response.getStatusCode() ) );
161 }
162 }
163
164 @Override
165 protected String getHelpUrl()
166 {
167 return null;
168 }
169
170 @Override
171 protected void insertButtons( JXToolBar toolbar )
172 {
173 if( getRequest().getResource() == null )
174 {
175 addToolbarComponents( toolbar );
176 }
177 }
178
179 protected JComponent buildEndpointComponent()
180 {
181 return getRequest().getResource() == null ? null : super.buildEndpointComponent();
182 }
183
184 @Override
185 protected JComponent buildToolbar()
186 {
187 if( getRequest().getResource() != null )
188 {
189 JPanel panel = new JPanel( new BorderLayout() );
190 panel.add( super.buildToolbar(), BorderLayout.NORTH );
191
192 JXToolBar toolbar = UISupport.createToolbar();
193 addToolbarComponents( toolbar );
194
195 panel.add( toolbar, BorderLayout.SOUTH );
196 return panel;
197 }
198 else
199 {
200 return super.buildToolbar();
201 }
202 }
203
204 protected void addToolbarComponents( JXToolBar toolbar )
205 {
206 toolbar.addSeparator();
207 methodCombo = new JComboBox( new Object[]{RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT,
208 RequestMethod.DELETE, RequestMethod.HEAD} );
209
210 methodCombo.setSelectedItem( getRequest().getMethod() );
211 methodCombo.setToolTipText( "Set desired HTTP method" );
212 methodCombo.addItemListener( new ItemListener()
213 {
214
215 public void itemStateChanged( ItemEvent e )
216 {
217 updatingRequest = true;
218 getRequest().setMethod( ( RequestMethod ) methodCombo.getSelectedItem() );
219 updatingRequest = false;
220 }
221 } );
222
223 toolbar.addLabeledFixed( "Method", methodCombo );
224 toolbar.addSeparator();
225
226 if( getRequest().getResource() != null )
227 {
228 acceptCombo = new JComboBox( getRequest().getResponseMediaTypes() );
229 acceptCombo.setEditable( true );
230 acceptCombo.setToolTipText( "Sets accepted encoding(s) for response" );
231 acceptCombo.setSelectedItem( getRequest().getAccept() );
232 acceptCombo.addItemListener( new ItemListener()
233 {
234 public void itemStateChanged( ItemEvent e )
235 {
236 updatingRequest = true;
237 getRequest().setAccept( String.valueOf( acceptCombo.getSelectedItem() ) );
238 updatingRequest = false;
239 }
240 } );
241
242 toolbar.addLabeledFixed( "Accept", acceptCombo );
243 toolbar.addSeparator();
244
245 pathTextField = new JUndoableTextField();
246 pathTextField.setPreferredSize( new Dimension( 200, 20 ) );
247 pathTextField.setText( getRequest().getResource().getPath() );
248 pathTextField.getDocument().addDocumentListener( new DocumentListenerAdapter()
249 {
250 @Override
251 public void update( Document document )
252 {
253 if( updating )
254 return;
255
256 updating = true;
257 getRequest().getResource().setPath( pathTextField.getText() );
258 updating = false;
259 }
260 } );
261
262 toolbar.addLabeledFixed( "Resource Path:", pathTextField );
263
264 pathLabel = new JLabel( getRequest().getResource().getFullPath() );
265 pathLabel.setPreferredSize( new Dimension( 200, 20 ) );
266
267 toolbar.addSeparator();
268 toolbar.addLabeledFixed( "Full Path:", pathLabel );
269 }
270 else
271 {
272 pathTextField = new JUndoableTextField();
273 pathTextField.setPreferredSize( new Dimension( 300, 20 ) );
274 pathTextField.setText( getRequest().getPath() );
275 pathTextField.getDocument().addDocumentListener( new DocumentListenerAdapter()
276 {
277 @Override
278 public void update( Document document )
279 {
280 getRequest().setPath( pathTextField.getText() );
281 }
282 } );
283
284 toolbar.addLabeledFixed( "Request URL:", pathTextField );
285 }
286
287 toolbar.addSeparator();
288 }
289
290 protected boolean release()
291 {
292 if( getRequest().getResource() != null )
293 {
294 getRequest().getResource().removePropertyChangeListener( this );
295 }
296
297 return super.release();
298 }
299
300 public class RestRequestMessageEditor extends
301 AbstractHttpRequestDesktopPanel<?, ?>.AbstractHttpRequestMessageEditor<RestRequestDocument>
302 {
303 public RestRequestMessageEditor( RestRequest modelItem )
304 {
305 super( new RestRequestDocument( modelItem ) );
306 }
307 }
308
309 public class RestResponseMessageEditor extends
310 AbstractHttpRequestDesktopPanel<?, ?>.AbstractHttpResponseMessageEditor<RestResponseDocument>
311 {
312 public RestResponseMessageEditor( RestRequest modelItem )
313 {
314 super( new RestResponseDocument( modelItem ) );
315 }
316 }
317
318 public class RestRequestDocument extends AbstractXmlDocument implements PropertyChangeListener
319 {
320 private final RestRequest modelItem;
321 private boolean updating;
322
323 public RestRequestDocument( RestRequest modelItem )
324 {
325 this.modelItem = modelItem;
326
327 modelItem.addPropertyChangeListener( this );
328 }
329
330 public RestRequest getRequest()
331 {
332 return modelItem;
333 }
334
335 public String getXml()
336 {
337 return getRequest().getRequestContent();
338 }
339
340 public void setXml( String xml )
341 {
342 if( !updating )
343 {
344 updating = true;
345 getRequest().setRequestContent( xml );
346 updating = false;
347 }
348 }
349
350 public void propertyChange( PropertyChangeEvent evt )
351 {
352 if( evt.getPropertyName().equals( RestRequest.REQUEST_PROPERTY ) && !updating )
353 {
354 updating = true;
355 fireXmlChanged( ( String ) evt.getOldValue(), ( String ) evt.getNewValue() );
356 updating = false;
357 }
358 }
359 }
360
361 public class RestResponseDocument extends AbstractXmlDocument implements PropertyChangeListener
362 {
363 private final RestRequest modelItem;
364
365 public RestResponseDocument( RestRequest modelItem )
366 {
367 this.modelItem = modelItem;
368
369 modelItem.addPropertyChangeListener( RestRequest.RESPONSE_PROPERTY, this );
370 }
371
372 public RestRequest getRequest()
373 {
374 return modelItem;
375 }
376
377 public String getXml()
378 {
379 return modelItem.getResponseContentAsXml();
380 }
381
382 public void setXml( String xml )
383 {
384 HttpResponse response = getRequest().getResponse();
385 if( response != null )
386 response.setResponseContent( xml );
387 }
388
389 public void propertyChange( PropertyChangeEvent evt )
390 {
391 fireXmlChanged( evt.getOldValue() == null ? null : ( ( HttpResponse ) evt.getOldValue() ).getContentAsString(),
392 getXml() );
393 }
394 }
395 }