View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.impl.rest.panels.request.views.content;
14  
15  import com.eviware.soapui.impl.rest.RestRepresentation;
16  import com.eviware.soapui.impl.rest.RestRequest;
17  import com.eviware.soapui.impl.rest.panels.request.AbstractRestRequestDesktopPanel.RestRequestDocument;
18  import com.eviware.soapui.impl.rest.panels.request.AbstractRestRequestDesktopPanel.RestRequestMessageEditor;
19  import com.eviware.soapui.impl.rest.panels.resource.RestParamsTable;
20  import com.eviware.soapui.impl.rest.support.RestUtils;
21  import com.eviware.soapui.impl.support.AbstractHttpRequest;
22  import com.eviware.soapui.impl.wsdl.support.xsd.SampleXmlUtil;
23  import com.eviware.soapui.support.DocumentListenerAdapter;
24  import com.eviware.soapui.support.UISupport;
25  import com.eviware.soapui.support.components.JXToolBar;
26  import com.eviware.soapui.support.editor.views.AbstractXmlEditorView;
27  import com.eviware.soapui.support.types.StringList;
28  import com.eviware.soapui.support.types.TupleList;
29  import com.eviware.soapui.support.xml.JXEditTextArea;
30  import com.eviware.soapui.support.xml.XmlUtils;
31  import org.apache.xmlbeans.SchemaGlobalElement;
32  import org.apache.xmlbeans.SchemaType;
33  
34  import javax.swing.*;
35  import javax.swing.text.Document;
36  import java.awt.*;
37  import java.awt.event.ActionEvent;
38  import java.awt.event.ItemEvent;
39  import java.awt.event.ItemListener;
40  import java.beans.PropertyChangeEvent;
41  import java.beans.PropertyChangeListener;
42  import java.net.URL;
43  
44  public class RestRequestContentView extends AbstractXmlEditorView<RestRequestDocument> implements PropertyChangeListener
45  {
46     private final RestRequest restRequest;
47     private JPanel contentPanel;
48     private JXEditTextArea contentEditor;
49     private boolean updatingRequest;
50     private JComponent panel;
51     private JComboBox mediaTypeCombo;
52     private JSplitPane split;
53     private JButton recreateButton;
54     private RestParamsTable paramsTable;
55     private JCheckBox postQueryCheckBox;
56  
57     public RestRequestContentView( RestRequestMessageEditor restRequestMessageEditor, RestRequest restRequest )
58     {
59        super( "Request", restRequestMessageEditor, RestRequestContentViewFactory.VIEW_ID );
60        this.restRequest = restRequest;
61  
62        restRequest.addPropertyChangeListener( this );
63     }
64  
65     public JComponent getComponent()
66     {
67        if( panel == null )
68        {
69           JPanel p = new JPanel( new BorderLayout() );
70  
71           p.add( buildToolbar(), BorderLayout.NORTH );
72           p.add( buildContent(), BorderLayout.CENTER );
73  
74           paramsTable = new RestParamsTable( restRequest.getParams(), true )
75           {
76              protected void insertAdditionalButtons( JXToolBar toolbar )
77              {
78                 toolbar.add( UISupport.createToolbarButton( new UpdateRestParamsAction() ) );
79              }
80           };
81  
82           split = UISupport.createVerticalSplit( paramsTable, p );
83  
84           panel = new JPanel( new BorderLayout() );
85           panel.add( split );
86  
87           SwingUtilities.invokeLater( new Runnable()
88           {
89              public void run()
90              {
91                 // wait for panel to get shown..
92                 if( panel.getHeight() == 0 )
93                 {
94                    SwingUtilities.invokeLater( this );
95                 }
96                 else
97                 {
98                    if( !restRequest.hasRequestBody() )
99                       split.setDividerLocation( 1.0F );
100                   else
101                      split.setDividerLocation( 0.5F );
102                }
103             }
104          } );
105       }
106 
107       return panel;
108    }
109 
110    @Override
111    public void release()
112    {
113       super.release();
114       restRequest.removePropertyChangeListener( this );
115    }
116 
117    private Component buildContent()
118    {
119       contentPanel = new JPanel( new BorderLayout() );
120 
121       contentEditor = JXEditTextArea.createXmlEditor( true );
122       contentEditor.setText( XmlUtils.prettyPrintXml( restRequest.getRequestContent() ) );
123 
124       contentEditor.getDocument().addDocumentListener( new DocumentListenerAdapter()
125       {
126 
127          @Override
128          public void update( Document document )
129          {
130             if( !updatingRequest )
131             {
132                updatingRequest = true;
133                restRequest.setRequestContent( contentEditor.getText() );
134                updatingRequest = false;
135             }
136          }
137       } );
138 
139       contentPanel.add( new JScrollPane( contentEditor ) );
140 
141       enableBodyComponents();
142 
143       return contentPanel;
144    }
145 
146    private void enableBodyComponents()
147    {
148       mediaTypeCombo.setEnabled( restRequest.hasRequestBody() && !restRequest.isPostQueryString() );
149       contentEditor.setEnabledAndEditable( restRequest.hasRequestBody() && !restRequest.isPostQueryString() );
150    }
151 
152    private Component buildToolbar()
153    {
154       JXToolBar toolbar = UISupport.createToolbar();
155 
156       mediaTypeCombo = new JComboBox( getRequestMediaTypes() );
157       mediaTypeCombo.setPreferredSize( new Dimension( 120, 20 ) );
158       mediaTypeCombo.setEnabled( restRequest.hasRequestBody() );
159       mediaTypeCombo.setEditable( true );
160       mediaTypeCombo.setSelectedItem( restRequest.getMediaType() );
161       mediaTypeCombo.addItemListener( new ItemListener()
162       {
163          public void itemStateChanged( ItemEvent e )
164          {
165             restRequest.setMediaType( mediaTypeCombo.getSelectedItem().toString() );
166          }
167       } );
168 
169       toolbar.addLabeledFixed( "Media Type", mediaTypeCombo );
170       toolbar.addSeparator();
171 
172       recreateButton = UISupport.createActionButton( new CreateDefaultRepresentationAction(), true );
173       recreateButton.setEnabled( canRecreate() );
174       toolbar.addFixed( recreateButton );
175 
176       toolbar.addSeparator();
177 
178       postQueryCheckBox = new JCheckBox( "Post QueryString", restRequest.isPostQueryString() );
179       postQueryCheckBox.setOpaque( false );
180       postQueryCheckBox.addItemListener( new ItemListener()
181       {
182          public void itemStateChanged( ItemEvent e )
183          {
184             restRequest.setPostQueryString( postQueryCheckBox.isSelected() );
185             enableBodyComponents();
186          }
187       } );
188 
189       postQueryCheckBox.setPreferredSize( new Dimension( 130, 20 ) );
190       toolbar.addFixed( postQueryCheckBox );
191 
192       toolbar.setMinimumSize( new Dimension( 50, 20) );
193       
194       return toolbar;
195    }
196 
197    private boolean canRecreate()
198    {
199       for( RestRepresentation representation : restRequest.getRepresentations( RestRepresentation.Type.REQUEST, restRequest.getMediaType() ) )
200       {
201          if( representation.getSchemaType() != null )
202             return true;
203       }
204 
205       return false;
206    }
207 
208    private Object[] getRequestMediaTypes()
209    {
210       StringList result = new StringList();
211 
212       for( RestRepresentation representation : restRequest.getRepresentations( RestRepresentation.Type.REQUEST, null ) )
213       {
214          if( !result.contains( representation.getMediaType() ) )
215             result.add( representation.getMediaType() );
216       }
217 
218       if( !result.contains( "application/xml" ) )
219          result.add( "application/xml" );
220 
221       if( !result.contains( "text/xml" ) )
222          result.add( "text/xml" );
223 
224       return result.toStringArray();
225    }
226 
227    public void propertyChange( PropertyChangeEvent evt )
228    {
229       if( evt.getPropertyName().equals( "request" ) && !updatingRequest )
230       {
231          updatingRequest = true;
232          contentEditor.setText( (String) evt.getNewValue() );
233          updatingRequest = false;
234       }
235       else if( evt.getPropertyName().equals( "method" ) )
236       {
237          enableBodyComponents();
238 
239          if( !restRequest.hasRequestBody() )
240          {
241             split.setDividerLocation( 1.0 );
242          }
243          else if( split.getDividerLocation() >= split.getHeight() - 20 )
244          {
245             split.setDividerLocation( 0.5 );
246          }
247       }
248       else if( evt.getPropertyName().equals( "mediaType" ) )
249       {
250          mediaTypeCombo.setSelectedItem( evt.getNewValue() );
251          recreateButton.setEnabled( canRecreate() );
252       }
253       else if( evt.getPropertyName().equals( AbstractHttpRequest.ATTACHMENTS_PROPERTY ) )
254       {
255          mediaTypeCombo.setModel( new DefaultComboBoxModel( getRequestMediaTypes()) );
256          mediaTypeCombo.setSelectedItem( restRequest.getMediaType() );
257       }
258    }
259 
260    @Override
261    public void setXml( String xml )
262    {
263    }
264 
265    public boolean saveDocument( boolean validate )
266    {
267       return false;
268    }
269 
270    public void setEditable( boolean enabled )
271    {
272       contentEditor.setEnabledAndEditable( enabled ? restRequest.hasRequestBody() : false );
273       mediaTypeCombo.setEnabled( enabled );
274       postQueryCheckBox.setEnabled( enabled );
275    }
276 
277    private class CreateDefaultRepresentationAction extends AbstractAction
278    {
279       private CreateDefaultRepresentationAction()
280       {
281          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/recreate_request.gif" ) );
282          putValue( Action.SHORT_DESCRIPTION, "Recreates a default representation from the schema" );
283       }
284 
285       public void actionPerformed( ActionEvent e )
286       {
287          TupleList<RestRepresentation, SchemaType> list = new TupleList<RestRepresentation, SchemaType>()
288          {
289             protected String toStringHandler( Tuple tuple )
290             {
291                return tuple.getValue2().getContainerField().getName().toString();
292             }
293          };
294 
295          for( RestRepresentation representation : restRequest.getRepresentations( RestRepresentation.Type.REQUEST, restRequest.getMediaType() ) )
296          {
297             SchemaType schemaType = representation.getSchemaType();
298             if( schemaType != null )
299             {
300                list.add( representation, schemaType );
301             }
302          }
303 
304          if( list.isEmpty() )
305          {
306             UISupport.showErrorMessage( "Missing recreatable representations for this method" );
307             return;
308          }
309 
310          TupleList<RestRepresentation, SchemaType>.Tuple result =
311                  (TupleList.Tuple) UISupport.prompt( "Select element to create", "Create default content", list.toArray() );
312          if( result == null )
313          {
314             return;
315          }
316 
317          restRequest.setRequestContent( SampleXmlUtil.createSampleForElement( (SchemaGlobalElement) result.getValue2().getContainerField() ) );
318       }
319    }
320 
321    private class UpdateRestParamsAction extends AbstractAction
322    {
323       private UpdateRestParamsAction()
324       {
325          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/add_property.gif" ) );
326          putValue( Action.SHORT_DESCRIPTION, "Updates this Requests params from a specified URL" );
327       }
328 
329       public void actionPerformed( ActionEvent e )
330       {
331          String str = UISupport.prompt( "Enter new url below", "Extract Params", "" );
332          if( str == null )
333             return;
334 
335          try
336          {
337             restRequest.getParams().resetValues();
338             RestUtils.extractParams( new URL( str ), restRequest.getParams(), false );
339             paramsTable.refresh();
340          }
341          catch( Exception e1 )
342          {
343             UISupport.showErrorMessage( e1 );
344          }
345       }
346    }
347 }