View Javadoc

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