View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 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;
14  
15  import java.awt.BorderLayout;
16  import java.awt.Component;
17  import java.awt.Dimension;
18  import java.awt.event.ItemEvent;
19  import java.awt.event.ItemListener;
20  import java.beans.PropertyChangeEvent;
21  import java.beans.PropertyChangeListener;
22  
23  import javax.swing.AbstractListModel;
24  import javax.swing.ComboBoxModel;
25  import javax.swing.DefaultComboBoxModel;
26  import javax.swing.DefaultListCellRenderer;
27  import javax.swing.JComboBox;
28  import javax.swing.JComponent;
29  import javax.swing.JLabel;
30  import javax.swing.JList;
31  import javax.swing.JPanel;
32  import javax.swing.text.Document;
33  
34  import com.eviware.soapui.impl.rest.RestMethod;
35  import com.eviware.soapui.impl.rest.RestRequestInterface;
36  import com.eviware.soapui.impl.rest.RestResource;
37  import com.eviware.soapui.impl.rest.support.RestParamProperty;
38  import com.eviware.soapui.impl.rest.support.RestUtils;
39  import com.eviware.soapui.impl.support.panels.AbstractHttpXmlRequestDesktopPanel;
40  import com.eviware.soapui.impl.wsdl.WsdlSubmitContext;
41  import com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestInterface;
42  import com.eviware.soapui.model.ModelItem;
43  import com.eviware.soapui.model.iface.Submit;
44  import com.eviware.soapui.model.iface.Request.SubmitException;
45  import com.eviware.soapui.model.support.TestPropertyListenerAdapter;
46  import com.eviware.soapui.model.testsuite.TestProperty;
47  import com.eviware.soapui.support.DocumentListenerAdapter;
48  import com.eviware.soapui.support.UISupport;
49  import com.eviware.soapui.support.components.JUndoableTextField;
50  import com.eviware.soapui.support.components.JXToolBar;
51  import com.eviware.soapui.support.propertyexpansion.PropertyExpansionPopupListener;
52  
53  public abstract class AbstractRestRequestDesktopPanel<T extends ModelItem, T2 extends RestRequestInterface> extends
54  		AbstractHttpXmlRequestDesktopPanel<T, T2>
55  {
56  	private boolean updatingRequest;
57  	private JUndoableTextField pathTextField;
58  	private JComboBox acceptCombo;
59  	private JLabel pathLabel;
60  	private boolean updating;
61  	private InternalTestPropertyListener testPropertyListener = new InternalTestPropertyListener();
62  	private RestParamPropertyChangeListener restParamPropertyChangeListener = new RestParamPropertyChangeListener();
63  	private JComboBox pathCombo;
64  
65  	public AbstractRestRequestDesktopPanel( T modelItem, T2 requestItem )
66  	{
67  		super( modelItem, requestItem );
68  
69  		if( requestItem.getResource() != null )
70  		{
71  			requestItem.getResource().addPropertyChangeListener( this );
72  		}
73  
74  		requestItem.addTestPropertyListener( testPropertyListener );
75  
76  		for( TestProperty param : requestItem.getParams().getProperties().values() )
77  		{
78  			( ( RestParamProperty )param ).addPropertyChangeListener( restParamPropertyChangeListener );
79  		}
80  	}
81  
82  	public void propertyChange( PropertyChangeEvent evt )
83  	{
84  		updateFullPathLabel();
85  
86  		if( evt.getPropertyName().equals( "accept" ) && !updatingRequest )
87  		{
88  			acceptCombo.setSelectedItem( evt.getNewValue() );
89  		}
90  		else if( evt.getPropertyName().equals( "responseMediaTypes" ) && !updatingRequest )
91  		{
92  			Object item = acceptCombo.getSelectedItem();
93  			acceptCombo.setModel( new DefaultComboBoxModel( ( Object[] )evt.getNewValue() ) );
94  			acceptCombo.setSelectedItem( item );
95  		}
96  		else if( (evt.getPropertyName().equals( "path" ) || evt.getPropertyName().equals( "restMethod" ))
97  				&& ( getRequest().getResource() == null || getRequest().getResource() == evt.getSource() ) )
98  		{
99  			if( pathLabel != null )
100 			{
101 				updateFullPathLabel();
102 			}
103 
104 			if( !updating && pathTextField != null )
105 			{
106 				updating = true;
107 				pathTextField.setText( ( String )evt.getNewValue() );
108 				pathTextField.setToolTipText( pathTextField.getText() );
109 				updating = false;
110 			}
111 		}
112 
113 		super.propertyChange( evt );
114 	}
115 
116 	@Override
117 	protected Submit doSubmit() throws SubmitException
118 	{
119 		return getRequest().submit( new WsdlSubmitContext( getModelItem() ), true );
120 	}
121 
122 	@Override
123 	protected String getHelpUrl()
124 	{
125 		return null;
126 	}
127 
128 	@Override
129 	protected void insertButtons( JXToolBar toolbar )
130 	{
131 		if( getRequest().getResource() == null )
132 		{
133 			addToolbarComponents( toolbar );
134 		}
135 	}
136 
137 	@Override
138 	protected JComponent buildToolbar()
139 	{
140 		if( getRequest().getResource() != null )
141 		{
142 			JPanel panel = new JPanel( new BorderLayout() );
143 			panel.add( super.buildToolbar(), BorderLayout.NORTH );
144 
145 			JXToolBar toolbar = UISupport.createToolbar();
146 			addToolbarComponents( toolbar );
147 
148 			panel.add( toolbar, BorderLayout.SOUTH );
149 			return panel;
150 		}
151 		else
152 		{
153 			return super.buildToolbar();
154 		}
155 	}
156 
157 	protected void addToolbarComponents( JXToolBar toolbar )
158 	{
159 		toolbar.addSeparator();
160 
161 		if( getRequest().getResource() != null )
162 		{
163 			acceptCombo = new JComboBox( getRequest().getResponseMediaTypes() );
164 			acceptCombo.setEditable( true );
165 			acceptCombo.setToolTipText( "Sets accepted encoding(s) for response" );
166 			acceptCombo.setSelectedItem( getRequest().getAccept() );
167 			acceptCombo.addItemListener( new ItemListener()
168 			{
169 				public void itemStateChanged( ItemEvent e )
170 				{
171 					updatingRequest = true;
172 					getRequest().setAccept( String.valueOf( acceptCombo.getSelectedItem() ) );
173 					updatingRequest = false;
174 				}
175 			} );
176 
177 			toolbar.addLabeledFixed( "Accept", acceptCombo );
178 			toolbar.addSeparator();
179 
180 			if( getRequest() instanceof RestTestRequestInterface )
181 			{
182 				pathCombo = new JComboBox( new PathComboBoxModel() );
183 				pathCombo.setRenderer( new RestMethodListCellRenderer() );
184 				pathCombo.setPreferredSize( new Dimension( 200, 20 ) );
185 				pathCombo.setSelectedItem( getRequest().getRestMethod() );
186 
187 				toolbar.addLabeledFixed( "Resource/Method:", pathCombo );
188 				toolbar.addSeparator();
189 			}
190 			else
191 			{
192 				toolbar.add( new JLabel( "Full Path: " ) );
193 			}
194 
195 			pathLabel = new JLabel();
196 			updateFullPathLabel();
197 
198 			toolbar.add( pathLabel );
199 		}
200 		else
201 		{
202 			pathTextField = new JUndoableTextField();
203 			pathTextField.setPreferredSize( new Dimension( 300, 20 ) );
204 			pathTextField.setText( getRequest().getPath() );
205 			pathTextField.setToolTipText( pathTextField.getText() );
206 			pathTextField.getDocument().addDocumentListener( new DocumentListenerAdapter()
207 			{
208 				@Override
209 				public void update( Document document )
210 				{
211 					if( updating )
212 						return;
213 
214 					updating = true;
215 					getRequest().setPath( pathTextField.getText() );
216 					updating = false;
217 				}
218 			} );
219 			PropertyExpansionPopupListener.enable( pathTextField, getModelItem() );
220 
221 			toolbar.addLabeledFixed( "Request URL:", pathTextField );
222 		}
223 
224 		toolbar.addSeparator();
225 	}
226 
227 	protected boolean release()
228 	{
229 		if( getRequest().getResource() != null )
230 		{
231 			getRequest().getResource().removePropertyChangeListener( this );
232 		}
233 
234 		getRequest().removeTestPropertyListener( testPropertyListener );
235 
236 		for( TestProperty param : getRequest().getParams().getProperties().values() )
237 		{
238 			( ( RestParamProperty )param ).removePropertyChangeListener( restParamPropertyChangeListener );
239 		}
240 
241 		return super.release();
242 	}
243 
244 	private class InternalTestPropertyListener extends TestPropertyListenerAdapter
245 	{
246 		@Override
247 		public void propertyValueChanged( String name, String oldValue, String newValue )
248 		{
249 			updateFullPathLabel();
250 		}
251 
252 		@Override
253 		public void propertyAdded( String name )
254 		{
255 			updateFullPathLabel();
256 
257 			getRequest().getParams().getProperty( name ).addPropertyChangeListener( restParamPropertyChangeListener );
258 		}
259 
260 		@Override
261 		public void propertyRemoved( String name )
262 		{
263 			updateFullPathLabel();
264 		}
265 
266 		@Override
267 		public void propertyRenamed( String oldName, String newName )
268 		{
269 			updateFullPathLabel();
270 		}
271 	}
272 
273 	private void updateFullPathLabel()
274 	{
275 		if( pathLabel != null && getRequest().getResource() != null )
276 		{
277 			String text = RestUtils.expandPath( getRequest().getResource().getFullPath(), getRequest().getParams(),
278 					getRequest() );
279 			pathLabel.setText( "[" + text + "]" );
280 			pathLabel.setToolTipText( text );
281 		}
282 	}
283 
284 	private class RestParamPropertyChangeListener implements PropertyChangeListener
285 	{
286 		public void propertyChange( PropertyChangeEvent evt )
287 		{
288 			updateFullPathLabel();
289 		}
290 	}
291 
292 	private class PathComboBoxModel extends AbstractListModel implements ComboBoxModel
293 	{
294 		public int getSize()
295 		{
296 			int sz = 0; 
297 			for( RestResource resource : getRequest().getResource().getService().getAllResources())
298 			{
299 				sz += resource.getRestMethodCount();
300 			}
301 			
302 			return sz;
303 		}
304 
305 		public Object getElementAt( int index )
306 		{
307 			int sz = 0; 
308 			for( RestResource resource : getRequest().getResource().getService().getAllResources())
309 			{
310 				if( index < sz + resource.getRestMethodCount() )
311 				{
312 					return resource.getRestMethodAt( index-sz );
313 				}
314 				
315 				sz += resource.getRestMethodCount();
316 			}
317 			
318 			return null;
319 		}
320 
321 		public void setSelectedItem( Object anItem )
322 		{
323 			( ( RestTestRequestInterface )getRequest() ).getTestStep().setRestMethod( (RestMethod)anItem );
324 		}
325 
326 		public Object getSelectedItem()
327 		{
328 			return getRequest().getRestMethod();
329 		}
330 	}
331 
332 	private class RestMethodListCellRenderer extends DefaultListCellRenderer
333 	{
334 		@Override
335 		public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected,
336 				boolean cellHasFocus )
337 		{
338 			Component result = super.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
339 
340 			if( value instanceof RestMethod )
341 			{
342 				RestMethod item = ( RestMethod )value;
343 				setIcon( item.getIcon() );
344 				setText( item.getResource().getName() + " -> " + item.getName() );
345 			}
346 
347 			return result;
348 		}
349 
350 	}
351 
352 }