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