View Javadoc

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