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  
43  public class RestRequestContentView extends AbstractXmlEditorView<RestRequestDocument> implements PropertyChangeListener
44  {
45     private final RestRequest restRequest;
46     private JPanel contentPanel;
47     private JXEditTextArea contentEditor;
48     private boolean updatingRequest;
49     private JComponent panel;
50     private JComboBox mediaTypeCombo;
51     private JSplitPane split;
52     private JButton recreateButton;
53     private RestParamsTable paramsTable;
54     private JCheckBox postQueryCheckBox;
55  
56     public RestRequestContentView( RestRequestMessageEditor restRequestMessageEditor, RestRequest restRequest )
57     {
58        super( "Request", restRequestMessageEditor, RestRequestContentViewFactory.VIEW_ID );
59        this.restRequest = restRequest;
60  
61        restRequest.addPropertyChangeListener( this );
62     }
63  
64     public JComponent getComponent()
65     {
66        if( panel == null )
67        {
68           JPanel p = new JPanel( new BorderLayout() );
69  
70           p.add( buildToolbar(), BorderLayout.NORTH );
71           p.add( buildContent(), BorderLayout.CENTER );
72  
73           paramsTable = new RestParamsTable( restRequest.getParams(), true )
74           {
75              protected void insertAdditionalButtons( JXToolBar toolbar )
76              {
77                 toolbar.add( UISupport.createToolbarButton( new UpdateRestParamsAction() ) );
78              }
79           };
80  
81           split = UISupport.createVerticalSplit( paramsTable, p );
82  
83           panel = new JPanel( new BorderLayout() );
84           panel.add( split );
85  
86           SwingUtilities.invokeLater( new Runnable()
87           {
88              public void run()
89              {
90                 // wait for panel to get shown..
91                 if( panel.getHeight() == 0 )
92                 {
93                    SwingUtilities.invokeLater( this );
94                 }
95                 else
96                 {
97                    if( !restRequest.hasRequestBody() )
98                       split.setDividerLocation( 1.0F );
99                    else
100                      split.setDividerLocation( 0.5F );
101                }
102             }
103          } );
104       }
105 
106       return panel;
107    }
108 
109    @Override
110    public void release()
111    {
112       super.release();
113       restRequest.removePropertyChangeListener( this );
114    }
115 
116    private Component buildContent()
117    {
118       contentPanel = new JPanel( new BorderLayout() );
119 
120       contentEditor = JXEditTextArea.createXmlEditor( true );
121       contentEditor.setText( XmlUtils.prettyPrintXml( restRequest.getRequestContent() ) );
122 
123       contentEditor.getDocument().addDocumentListener( new DocumentListenerAdapter()
124       {
125 
126          @Override
127          public void update( Document document )
128          {
129             if( !updatingRequest )
130             {
131                updatingRequest = true;
132                restRequest.setRequestContent( getText( document ) );
133                updatingRequest = false;
134             }
135          }
136       } );
137 
138       contentPanel.add( new JScrollPane( contentEditor ) );
139 
140       enableBodyComponents();
141 
142       return contentPanel;
143    }
144 
145    private void enableBodyComponents()
146    {
147       mediaTypeCombo.setEnabled( restRequest.hasRequestBody() && !restRequest.isPostQueryString() );
148       contentEditor.setEnabledAndEditable( restRequest.hasRequestBody() && !restRequest.isPostQueryString() );
149       postQueryCheckBox.setEnabled( restRequest.hasRequestBody() );
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.setToolTipText( "Controls if Query-parameters should be put in message body" );
180       postQueryCheckBox.setOpaque( false );
181       postQueryCheckBox.addItemListener( new ItemListener()
182       {
183          public void itemStateChanged( ItemEvent e )
184          {
185             restRequest.setPostQueryString( postQueryCheckBox.isSelected() );
186             enableBodyComponents();
187          }
188       } );
189 
190       postQueryCheckBox.setPreferredSize( new Dimension( 130, 20 ) );
191       toolbar.addFixed( postQueryCheckBox );
192 
193       toolbar.setMinimumSize( new Dimension( 50, 20 ) );
194 
195       return toolbar;
196    }
197 
198    private boolean canRecreate()
199    {
200       for( RestRepresentation representation : restRequest.getRepresentations( RestRepresentation.Type.REQUEST, restRequest.getMediaType() ) )
201       {
202          if( representation.getSchemaType() != null )
203             return true;
204       }
205 
206       return false;
207    }
208 
209    private Object[] getRequestMediaTypes()
210    {
211       StringList result = new StringList();
212 
213       for( RestRepresentation representation : restRequest.getRepresentations( RestRepresentation.Type.REQUEST, null ) )
214       {
215          if( !result.contains( representation.getMediaType() ) )
216             result.add( representation.getMediaType() );
217       }
218 
219       if( !result.contains( "application/xml" ) )
220          result.add( "application/xml" );
221 
222       if( !result.contains( "text/xml" ) )
223          result.add( "text/xml" );
224 
225       return result.toStringArray();
226    }
227 
228    public void propertyChange( PropertyChangeEvent evt )
229    {
230       if( evt.getPropertyName().equals( "request" ) && !updatingRequest )
231       {
232          updatingRequest = true;
233          contentEditor.setText( (String) evt.getNewValue() );
234          updatingRequest = false;
235       }
236       else if( evt.getPropertyName().equals( "method" ) )
237       {
238          enableBodyComponents();
239 
240          if( !restRequest.hasRequestBody() )
241          {
242             split.setDividerLocation( 1.0 );
243          }
244          else if( split.getDividerLocation() >= split.getHeight() - 20 )
245          {
246             split.setDividerLocation( 0.5 );
247          }
248       }
249       else if( evt.getPropertyName().equals( "mediaType" ) )
250       {
251          mediaTypeCombo.setSelectedItem( evt.getNewValue() );
252          recreateButton.setEnabled( canRecreate() );
253       }
254       else if( evt.getPropertyName().equals( AbstractHttpRequest.ATTACHMENTS_PROPERTY ) )
255       {
256          mediaTypeCombo.setModel( new DefaultComboBoxModel( getRequestMediaTypes() ) );
257          mediaTypeCombo.setSelectedItem( restRequest.getMediaType() );
258       }
259    }
260 
261    @Override
262    public void setXml( String xml )
263    {
264    }
265 
266    public boolean saveDocument( boolean validate )
267    {
268       return false;
269    }
270 
271    public void setEditable( boolean enabled )
272    {
273       contentEditor.setEnabledAndEditable( enabled ? restRequest.hasRequestBody() : false );
274       mediaTypeCombo.setEnabled( enabled );
275       postQueryCheckBox.setEnabled( enabled );
276    }
277 
278    public RestParamsTable getParamsTable()
279    {
280       return paramsTable;
281    }
282 
283    private class CreateDefaultRepresentationAction extends AbstractAction
284    {
285       private CreateDefaultRepresentationAction()
286       {
287          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/recreate_request.gif" ) );
288          putValue( Action.SHORT_DESCRIPTION, "Recreates a default representation from the schema" );
289       }
290 
291       public void actionPerformed( ActionEvent e )
292       {
293          TupleList<RestRepresentation, SchemaType> list = new TupleList<RestRepresentation, SchemaType>()
294          {
295             protected String toStringHandler( Tuple tuple )
296             {
297                return tuple.getValue2().getContainerField().getName().toString();
298             }
299          };
300 
301          for( RestRepresentation representation : restRequest.getRepresentations( RestRepresentation.Type.REQUEST, restRequest.getMediaType() ) )
302          {
303             SchemaType schemaType = representation.getSchemaType();
304             if( schemaType != null )
305             {
306                list.add( representation, schemaType );
307             }
308          }
309 
310          if( list.isEmpty() )
311          {
312             UISupport.showErrorMessage( "Missing recreatable representations for this method" );
313             return;
314          }
315 
316          TupleList<RestRepresentation, SchemaType>.Tuple result =
317                  (TupleList.Tuple) UISupport.prompt( "Select element to create", "Create default content", list.toArray() );
318          if( result == null )
319          {
320             return;
321          }
322 
323          restRequest.setRequestContent( SampleXmlUtil.createSampleForElement( (SchemaGlobalElement) result.getValue2().getContainerField() ) );
324       }
325    }
326 
327    private class UpdateRestParamsAction extends AbstractAction
328    {
329       private UpdateRestParamsAction()
330       {
331          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/add_property.gif" ) );
332          putValue( Action.SHORT_DESCRIPTION, "Updates this Requests params from a specified URL" );
333       }
334 
335       public void actionPerformed( ActionEvent e )
336       {
337          String str = UISupport.prompt( "Enter new url below", "Extract Params", "" );
338          if( str == null )
339             return;
340 
341          try
342          {
343             restRequest.getParams().resetValues();
344             RestUtils.extractParams( str, restRequest.getParams(), false );
345             paramsTable.refresh();
346          }
347          catch( Exception e1 )
348          {
349             UISupport.showErrorMessage( e1 );
350          }
351       }
352    }
353 }