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.support.propertyexpansion;
14  
15  import java.awt.BorderLayout;
16  import java.awt.Color;
17  import java.awt.Container;
18  import java.awt.dnd.DnDConstants;
19  import java.awt.dnd.DropTarget;
20  import java.awt.event.ActionEvent;
21  
22  import javax.swing.AbstractAction;
23  import javax.swing.BorderFactory;
24  import javax.swing.JButton;
25  import javax.swing.JMenu;
26  import javax.swing.JPanel;
27  import javax.swing.JPopupMenu;
28  import javax.swing.JSeparator;
29  import javax.swing.JTextField;
30  import javax.swing.event.PopupMenuEvent;
31  import javax.swing.event.PopupMenuListener;
32  import javax.swing.text.JTextComponent;
33  
34  import org.apache.xmlbeans.XmlObject;
35  
36  import com.eviware.soapui.impl.support.AbstractHttpRequest;
37  import com.eviware.soapui.impl.support.AbstractHttpRequestInterface;
38  import com.eviware.soapui.impl.wsdl.MutableTestPropertyHolder;
39  import com.eviware.soapui.impl.wsdl.WsdlProject;
40  import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
41  import com.eviware.soapui.impl.wsdl.mock.WsdlMockResponse;
42  import com.eviware.soapui.impl.wsdl.mock.WsdlMockService;
43  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.GroovyEditor;
44  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
45  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep;
46  import com.eviware.soapui.model.ModelItem;
47  import com.eviware.soapui.model.TestModelItem;
48  import com.eviware.soapui.model.TestPropertyHolder;
49  import com.eviware.soapui.model.iface.Operation;
50  import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
51  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionImpl;
52  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
53  import com.eviware.soapui.model.testsuite.TestProperty;
54  import com.eviware.soapui.support.StringUtils;
55  import com.eviware.soapui.support.UISupport;
56  import com.eviware.soapui.support.components.GroovyEditorComponent;
57  import com.eviware.soapui.support.components.ShowPopupAction;
58  import com.eviware.soapui.support.propertyexpansion.scrollmenu.ScrollableMenu;
59  import com.eviware.soapui.support.xml.JXEditTextArea;
60  import com.eviware.soapui.support.xml.XmlUtils;
61  
62  public class PropertyExpansionPopupListener implements PopupMenuListener
63  {
64  	private final Container targetMenu;
65  	private final ModelItem modelItem;
66  	private final PropertyExpansionTarget target;
67  
68  	public PropertyExpansionPopupListener( Container transferMenu, ModelItem modelItem, PropertyExpansionTarget target )
69  	{
70  		this.modelItem = modelItem;
71  		this.target = target;
72  
73  		this.targetMenu = transferMenu;
74  	}
75  
76  	public void popupMenuCanceled( PopupMenuEvent arg0 )
77  	{
78  	}
79  
80  	public void popupMenuWillBecomeInvisible( PopupMenuEvent arg0 )
81  	{
82  	}
83  
84  	public void popupMenuWillBecomeVisible( PopupMenuEvent arg0 )
85  	{
86  		// create transfer menus
87  		targetMenu.removeAll();
88  
89  		WsdlTestStep testStep = null;
90  		WsdlTestCase testCase = null;
91  		WsdlTestSuite testSuite = null;
92  		WsdlProject project = null;
93  		WsdlMockService mockService = null;
94  		WsdlMockResponse mockResponse = null;
95  
96  		if( modelItem instanceof WsdlTestStep )
97  		{
98  			testStep = ( WsdlTestStep )modelItem;
99  			testCase = testStep.getTestCase();
100 			testSuite = testCase.getTestSuite();
101 			project = testSuite.getProject();
102 		}
103 		else if( modelItem instanceof WsdlTestCase )
104 		{
105 			testCase = ( WsdlTestCase )modelItem;
106 			testSuite = testCase.getTestSuite();
107 			project = testSuite.getProject();
108 		}
109 		else if( modelItem instanceof WsdlTestSuite )
110 		{
111 			testSuite = ( WsdlTestSuite )modelItem;
112 			project = testSuite.getProject();
113 		}
114 		else if( modelItem instanceof WsdlMockService )
115 		{
116 			project = ( ( WsdlMockService )modelItem ).getProject();
117 		}
118 		else if( modelItem instanceof WsdlMockResponse )
119 		{
120 			mockResponse = ( WsdlMockResponse )modelItem;
121 			mockService = ( mockResponse ).getMockOperation().getMockService();
122 			project = mockService.getProject();
123 		}
124 		else if( modelItem instanceof WsdlProject )
125 		{
126 			project = ( WsdlProject )modelItem;
127 		}
128 		else if( modelItem instanceof AbstractHttpRequestInterface<?> )
129 		{
130 			project = ( ( AbstractHttpRequest<?> )modelItem ).getOperation().getInterface().getProject();
131 		}
132 		else if( modelItem instanceof Operation )
133 		{
134 			project = ( WsdlProject )( ( Operation )modelItem ).getInterface().getProject();
135 		}
136 
137 		TestPropertyHolder globalProperties = PropertyExpansionUtils.getGlobalProperties();
138 		if( globalProperties.getProperties().size() > 0 )
139 			targetMenu.add( createPropertyMenu( "Global", globalProperties ) );
140 
141 		if( project != null )
142 			targetMenu.add( createPropertyMenu( "Project: [" + project.getName() + "]", project ) );
143 
144 		if( testSuite != null )
145 			targetMenu.add( createPropertyMenu( "TestSuite: [" + testSuite.getName() + "]", testSuite ) );
146 
147 		if( mockService != null )
148 			targetMenu.add( createPropertyMenu( "MockService: [" + mockService.getName() + "]", mockService ) );
149 
150 		if( mockResponse != null )
151 			targetMenu.add( createPropertyMenu( "MockResponse: [" + mockResponse.getName() + "]", mockResponse ) );
152 
153 		if( testCase != null )
154 		{
155 			targetMenu.add( createPropertyMenu( "TestCase: [" + testCase.getName() + "]", testCase ) );
156 
157 			for( int c = 0; c < testCase.getTestStepCount(); c++ )
158 			{
159 				testStep = testCase.getTestStepAt( c );
160 				if( testStep.getPropertyNames().length == 0 )
161 					continue;
162 
163 				if( targetMenu.getComponentCount() == 3 )
164 					targetMenu.add( new JSeparator() );
165 
166 				targetMenu.add( createPropertyMenu( "Step " + ( c + 1 ) + ": [" + testStep.getName() + "]", testStep ) );
167 			}
168 		}
169 
170 	}
171 
172 	private JMenu createPropertyMenu( String string, TestPropertyHolder holder )
173 	{
174 		ScrollableMenu menu = new ScrollableMenu( string );
175 
176 		if( holder instanceof TestModelItem )
177 			menu.setIcon( ( ( TestModelItem )holder ).getIcon() );
178 
179 		String[] propertyNames = holder.getPropertyNames();
180 
181 		for( String name : propertyNames )
182 		{
183 			menu.add( new TransferFromPropertyActionInvoker( holder, name ) );
184 		}
185 
186 		if( holder instanceof MutableTestPropertyHolder )
187 		{
188 			menu.addHeader( new TransferFromPropertyActionInvoker( ( MutableTestPropertyHolder )holder ) );
189 		}
190 
191 		return menu;
192 	}
193 
194 	public class TransferFromPropertyActionInvoker extends AbstractAction
195 	{
196 		private TestPropertyHolder sourceStep;
197 		private String sourceProperty;
198 
199 		public TransferFromPropertyActionInvoker( TestPropertyHolder sourceStep, String sourceProperty )
200 		{
201 			super( "Property [" + sourceProperty + "]" );
202 			this.sourceStep = sourceStep;
203 			this.sourceProperty = sourceProperty;
204 		}
205 
206 		public TransferFromPropertyActionInvoker( MutableTestPropertyHolder testStep )
207 		{
208 			super( "Create new.." );
209 			this.sourceStep = testStep;
210 		}
211 
212 		public void actionPerformed( ActionEvent arg0 )
213 		{
214 			if( sourceProperty == null && sourceStep instanceof MutableTestPropertyHolder )
215 			{
216 				MutableTestPropertyHolder step = ( MutableTestPropertyHolder )sourceStep;
217 				sourceProperty = target.getNameForCreation();
218 
219 				sourceProperty = UISupport.prompt( "Specify name of source property to create", "Create source property",
220 						sourceProperty );
221 				while( sourceProperty != null && step.getProperty( sourceProperty ) != null )
222 				{
223 					sourceProperty = UISupport.prompt( "Name is taken, specify unique name of source property to create",
224 							"Create source property", sourceProperty );
225 				}
226 
227 				if( sourceProperty == null )
228 				{
229 					return;
230 				}
231 
232 				( ( MutableTestPropertyHolder )sourceStep ).addProperty( sourceProperty );
233 			}
234 
235 			String sourceXPath = "";
236 
237 			String val = sourceStep.getPropertyValue( sourceProperty );
238 
239 			try
240 			{
241 				if( StringUtils.isNullOrEmpty( val ) )
242 				{
243 					String defaultValue = sourceStep.getProperty( sourceProperty ).getDefaultValue();
244 					if( StringUtils.hasContent( defaultValue ) )
245 					{
246 						if( UISupport.confirm( "Missing property value, use default value instead?", "Get Data" ) )
247 						{
248 							val = defaultValue;
249 						}
250 					}
251 				}
252 
253 				if( XmlUtils.seemsToBeXml( val ) )
254 				{
255 					XmlObject.Factory.parse( val );
256 					sourceXPath = UISupport.selectXPath( "Select XPath", "Select source xpath for property transfer", val,
257 							null );
258 				}
259 			}
260 			catch( Throwable e )
261 			{
262 				// just ignore.. this wasn't xml..
263 			}
264 
265 			if( StringUtils.hasContent( sourceXPath ) )
266 			{
267 				sourceXPath = PropertyExpansionUtils.shortenXPathForPropertyExpansion( sourceXPath, val );
268 			}
269 
270 			TestProperty property = sourceStep.getProperty( sourceProperty );
271 			PropertyExpansion pe = new PropertyExpansionImpl( property, sourceXPath );
272 
273 			String valueForCreation = target.getValueForCreation();
274 			target.insertPropertyExpansion( pe, null );
275 
276 			if( !StringUtils.hasContent( sourceXPath ) && StringUtils.hasContent( valueForCreation )
277 					&& !property.isReadOnly() )
278 			{
279 				valueForCreation = UISupport.prompt( "Init property value to", "Get Data", valueForCreation );
280 				if( valueForCreation != null )
281 				{
282 					property.setValue( valueForCreation );
283 				}
284 			}
285 		}
286 	}
287 
288 	public static void addMenu( JPopupMenu popup, String menuName, ModelItem item, PropertyExpansionTarget component )
289 	{
290 		ScrollableMenu menu = new ScrollableMenu( menuName );
291 		popup.add( menu );
292 		popup.addPopupMenuListener( new PropertyExpansionPopupListener( menu, item, component ) );
293 	}
294 
295 	public static void enable( JTextComponent textField, ModelItem modelItem, JPopupMenu popup )
296 	{
297 		JTextComponentPropertyExpansionTarget target = new JTextComponentPropertyExpansionTarget( textField, modelItem );
298 		DropTarget dropTarget = new DropTarget( textField, new PropertyExpansionDropTarget( target ) );
299 		dropTarget.setDefaultActions( DnDConstants.ACTION_COPY_OR_MOVE );
300 
301 		textField.setComponentPopupMenu( popup );
302 
303 		if( popup != null )
304 		{
305 			PropertyExpansionPopupListener.addMenu( popup, "Get Data..", target.getContextModelItem(), target );
306 		}
307 	}
308 
309 	public static JPanel addPropertyExpansionPopup( JTextField textField, JPopupMenu popup, ModelItem modelItem )
310 	{
311 		PropertyExpansionPopupListener.enable( textField, modelItem, popup );
312 
313 		JButton popupButton = new JButton();
314 		popupButton.setAction( new ShowPopupAction( textField, popupButton ) );
315 		popupButton.setBackground( Color.WHITE );
316 		popupButton.setForeground( Color.WHITE );
317 		popupButton.setBorder( null );
318 		popupButton.setOpaque( true );
319 		JPanel panel = new JPanel( new BorderLayout() );
320 		panel.add( textField, BorderLayout.CENTER );
321 		panel.add( popupButton, BorderLayout.EAST );
322 		panel.setBorder( textField.getBorder() );
323 		textField.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2 ) );
324 
325 		return panel;
326 	}
327 
328 	public static void enable( JXEditTextArea textField, ModelItem modelItem )
329 	{
330 		JXEditTextAreaPropertyExpansionTarget target = new JXEditTextAreaPropertyExpansionTarget( textField, modelItem );
331 		DropTarget dropTarget = new DropTarget( textField, new PropertyExpansionDropTarget( target ) );
332 		dropTarget.setDefaultActions( DnDConstants.ACTION_COPY_OR_MOVE );
333 
334 		JPopupMenu popup = textField.getRightClickPopup();
335 
336 		if( popup != null )
337 		{
338 			PropertyExpansionPopupListener.addMenu( popup, "Get Data..", target.getContextModelItem(), target );
339 		}
340 	}
341 
342 	public static void enable( GroovyEditor groovyEditor, ModelItem modelItem )
343 	{
344 		GroovyEditorPropertyExpansionTarget target = new GroovyEditorPropertyExpansionTarget( groovyEditor, modelItem );
345 		DropTarget dropTarget = new DropTarget( groovyEditor.getEditArea(), new PropertyExpansionDropTarget( target ) );
346 		dropTarget.setDefaultActions( DnDConstants.ACTION_COPY_OR_MOVE );
347 
348 		JPopupMenu popup = groovyEditor.getEditArea().getComponentPopupMenu();
349 
350 		if( popup != null )
351 		{
352 			ScrollableMenu menu = new ScrollableMenu( "Get Data.." );
353 			popup.insert( menu, 0 );
354 			popup.addPopupMenuListener( new PropertyExpansionPopupListener( menu, target.getContextModelItem(), target ) );
355 			popup.insert( new JSeparator(), 1 );
356 		}
357 	}
358 
359 	public static void enable( JTextComponent textField, ModelItem modelItem )
360 	{
361 		JPopupMenu popupMenu = textField.getComponentPopupMenu();
362 		if( popupMenu == null )
363 		{
364 			popupMenu = new JPopupMenu();
365 			textField.setComponentPopupMenu( popupMenu );
366 		}
367 
368 		enable( textField, modelItem, popupMenu );
369 	}
370 
371 	public static void disable( GroovyEditor editor )
372 	{
373 	}
374 
375 	public static void enable( GroovyEditorComponent gec, ModelItem modelItem )
376 	{
377 		enable( gec.getEditor(), modelItem );
378 	}
379 }