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