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.impl.wsdl.actions.iface;
14  
15  import java.io.File;
16  import java.util.ArrayList;
17  import java.util.List;
18  
19  import com.eviware.soapui.SoapUI;
20  import com.eviware.soapui.impl.wsdl.WsdlInterface;
21  import com.eviware.soapui.impl.wsdl.WsdlOperation;
22  import com.eviware.soapui.impl.wsdl.WsdlRequest;
23  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
24  import com.eviware.soapui.impl.wsdl.support.PathUtils;
25  import com.eviware.soapui.impl.wsdl.support.soap.SoapUtils;
26  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
27  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequest;
28  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep;
29  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep;
30  import com.eviware.soapui.model.ModelItem;
31  import com.eviware.soapui.model.iface.Request;
32  import com.eviware.soapui.model.propertyexpansion.DefaultPropertyExpansionContext;
33  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContext;
34  import com.eviware.soapui.model.testsuite.TestCase;
35  import com.eviware.soapui.model.testsuite.TestSuite;
36  import com.eviware.soapui.support.UISupport;
37  import com.eviware.soapui.support.action.support.AbstractSoapUIAction;
38  import com.eviware.soapui.support.components.ModelItemListDesktopPanel;
39  import com.eviware.soapui.support.xml.XmlUtils;
40  import com.eviware.x.form.XFormDialog;
41  import com.eviware.x.form.XFormField;
42  import com.eviware.x.form.XFormFieldListener;
43  import com.eviware.x.form.support.ADialogBuilder;
44  import com.eviware.x.form.support.AField;
45  import com.eviware.x.form.support.AForm;
46  import com.eviware.x.form.support.AField.AFieldType;
47  
48  /***
49   * Updates the definition of a WsdlInterface.
50   * 
51   * @author Ole.Matzura
52   */
53  
54  public class UpdateInterfaceAction extends AbstractSoapUIAction<WsdlInterface>
55  {
56  	public static final String SOAPUI_ACTION_ID = "UpdateInterfaceAction";
57  	private XFormDialog dialog = null;
58  
59  	public UpdateInterfaceAction()
60  	{
61  		this( "Update Definition", "Reloads the definition for this interface and its operations" );
62  	}
63  
64  	protected UpdateInterfaceAction( String name, String description )
65  	{
66  		super( name, description );
67  	}
68  
69  	public void perform( WsdlInterface iface, Object param )
70  	{
71  		if( RemoveInterfaceAction.hasRunningDependingTests( iface ) )
72  		{
73  			UISupport.showErrorMessage( "Cannot update Interface due to running depending tests" );
74  			return;
75  		}
76  
77  		if( dialog == null )
78  		{
79  			dialog = ADialogBuilder.buildDialog( Form.class );
80  			dialog.setBooleanValue( Form.CREATE_REQUESTS, true );
81  			dialog.getFormField( Form.CREATE_BACKUPS ).setEnabled( false );
82  			dialog.getFormField( Form.RECREATE_OPTIONAL ).setEnabled( false );
83  			dialog.getFormField( Form.KEEP_EXISTING ).setEnabled( false );
84  			dialog.getFormField( Form.RECREATE_REQUESTS ).addFormFieldListener( new XFormFieldListener()
85  			{
86  
87  				public void valueChanged( XFormField sourceField, String newValue, String oldValue )
88  				{
89  					boolean enabled = dialog.getBooleanValue( Form.RECREATE_REQUESTS );
90  
91  					dialog.getFormField( Form.CREATE_BACKUPS ).setEnabled( enabled );
92  					dialog.getFormField( Form.RECREATE_OPTIONAL ).setEnabled( enabled );
93  					dialog.getFormField( Form.KEEP_EXISTING ).setEnabled( enabled );
94  				}
95  			} );
96  		}
97  
98  		dialog.setValue( Form.DEFINITION_URL, iface.getDefinition() );
99  		dialog.getFormField( Form.DEFINITION_URL ).setToolTip( PathUtils.expandPath( iface.getDefinition(), iface ) );
100 		if( !dialog.show() )
101 			return;
102 
103 		PropertyExpansionContext context = new DefaultPropertyExpansionContext( iface.getProject().getModelItem() );
104 		String url = dialog.getValue( Form.DEFINITION_URL );
105 		if( url == null || url.trim().length() == 0 )
106 			return;
107 
108 		String expUrl = PathUtils.expandPath( url, iface );
109 		if( expUrl.trim().length() == 0 )
110 			return;
111 
112 		try
113 		{
114 			File file = new File( expUrl );
115 			if( file.exists() )
116 				expUrl = file.toURI().toURL().toString();
117 		}
118 		catch( Exception e )
119 		{
120 			SoapUI.logError( e );
121 		}
122 
123 		boolean createRequests = dialog.getBooleanValue( Form.CREATE_REQUESTS );
124 
125 		try
126 		{
127 			if( iface.updateDefinition( expUrl, createRequests ) )
128 			{
129 				afterUpdate( iface );
130 				if( !url.equals( expUrl ) )
131 					iface.setDefinition( url, false );
132 			}
133 			else
134 				UISupport.showInfoMessage( "Update of interface failed", "Update Definition" );
135 		}
136 		catch( Exception e1 )
137 		{
138 			UISupport.showInfoMessage( "Failed to update interface: [" + e1 + "]", "Update Definition" );
139 			SoapUI.logError( e1 );
140 		}
141 	}
142 
143 	protected void afterUpdate( WsdlInterface iface ) throws Exception
144 	{
145 		if( dialog.getBooleanValue( Form.RECREATE_REQUESTS ) )
146 		{
147 			boolean buildOptional = dialog.getBooleanValue( Form.RECREATE_OPTIONAL );
148 			boolean createBackups = dialog.getBooleanValue( Form.CREATE_BACKUPS );
149 			boolean keepExisting = dialog.getBooleanValue( Form.KEEP_EXISTING );
150 			boolean keepHeaders = dialog.getBooleanValue( Form.KEEP_HEADERS );
151 
152 			List<ModelItem> updated = new ArrayList<ModelItem>();
153 
154 			updated.addAll( recreateRequests( iface, buildOptional, createBackups, keepExisting, keepHeaders ) );
155 
156 			if( dialog.getBooleanValue( Form.UPDATE_TESTREQUESTS ) )
157 				updated.addAll( recreateTestRequests( iface, buildOptional, createBackups, keepExisting, keepHeaders ) );
158 
159 			UISupport.showInfoMessage( "Update of interface successfull, [" + updated.size()
160 					+ "] Requests/TestRequests have" + " been updated.", "Update Definition" );
161 
162 			if( dialog.getBooleanValue( Form.OPEN_LIST ) )
163 			{
164 				UISupport
165 						.showDesktopPanel( new ModelItemListDesktopPanel( "Updated Requests/TestRequests",
166 								"The following Request/TestRequests where updated", updated.toArray( new ModelItem[updated
167 										.size()] ) ) );
168 			}
169 		}
170 		else
171 		{
172 			UISupport.showInfoMessage( "Update of interface successful", "Update Definition" );
173 		}
174 	}
175 
176 	protected List<Request> recreateRequests( WsdlInterface iface, boolean buildOptional, boolean createBackups,
177 			boolean keepExisting, boolean keepHeaders )
178 	{
179 		int count = 0;
180 
181 		List<Request> result = new ArrayList<Request>();
182 
183 		// first check operations
184 		for( int c = 0; c < iface.getOperationCount(); c++ )
185 		{
186 			WsdlOperation operation = iface.getOperationAt( c );
187 			String newRequest = operation.createRequest( buildOptional );
188 			List<Request> requests = operation.getRequestList();
189 
190 			for( Request request : requests )
191 			{
192 				String requestContent = request.getRequestContent();
193 
194 				if( keepHeaders )
195 				{
196 					newRequest = SoapUtils.transferSoapHeaders( requestContent, newRequest, iface.getSoapVersion() );
197 				}
198 
199 				String req = XmlUtils.transferValues( requestContent, newRequest );
200 
201 				// changed?
202 				if( !req.equals( requestContent ) )
203 				{
204 					if( !XmlUtils.prettyPrintXml( req ).equals( XmlUtils.prettyPrintXml( requestContent ) ) )
205 					{
206 						if( createBackups )
207 						{
208 							WsdlRequest backupRequest = operation.addNewRequest( "Backup of [" + request.getName() + "]" );
209 							( ( WsdlRequest )request ).copyTo( backupRequest, false, false );
210 						}
211 
212 						( ( WsdlRequest )request ).setRequestContent( req );
213 						count++ ;
214 
215 						result.add( request );
216 					}
217 				}
218 			}
219 		}
220 
221 		return result;
222 	}
223 
224 	private List<WsdlTestRequestStep> recreateTestRequests( WsdlInterface iface, boolean buildOptional,
225 			boolean createBackups, boolean keepExisting, boolean keepHeaders )
226 	{
227 		int count = 0;
228 
229 		List<WsdlTestRequestStep> result = new ArrayList<WsdlTestRequestStep>();
230 
231 		// now check testsuites..
232 		for( TestSuite testSuite : iface.getProject().getTestSuiteList() )
233 		{
234 			for( TestCase testCase : testSuite.getTestCaseList() )
235 			{
236 				int testStepCount = testCase.getTestStepCount();
237 				for( int c = 0; c < testStepCount; c++ )
238 				{
239 					WsdlTestStep testStep = ( WsdlTestStep )testCase.getTestStepAt( c );
240 					if( testStep instanceof WsdlTestRequestStep )
241 					{
242 						WsdlTestRequest testRequest = ( ( WsdlTestRequestStep )testStep ).getTestRequest();
243 						if( testRequest.getOperation().getInterface() == iface )
244 						{
245 							String newRequest = testRequest.getOperation().createRequest( buildOptional );
246 
247 							if( keepHeaders )
248 							{
249 								newRequest = SoapUtils.transferSoapHeaders( testRequest.getRequestContent(), newRequest, iface
250 										.getSoapVersion() );
251 							}
252 
253 							if( keepExisting )
254 								newRequest = XmlUtils.transferValues( testRequest.getRequestContent(), newRequest );
255 
256 							// changed?
257 							if( !newRequest.equals( testRequest.getRequestContent() ) )
258 							{
259 								if( createBackups )
260 								{
261 									( ( WsdlTestCase )testCase ).importTestStep( testStep,
262 											"Backup of [" + testStep.getName() + "]", -1, true ).setDisabled( true );
263 								}
264 
265 								( ( WsdlRequest )testRequest ).setRequestContent( newRequest );
266 								count++ ;
267 
268 								result.add( ( WsdlTestRequestStep )testStep );
269 							}
270 						}
271 					}
272 				}
273 			}
274 		}
275 
276 		return result;
277 	}
278 
279 	@AForm( description = "Specify Update Definition options", name = "Update Definition", helpUrl = HelpUrls.UPDATE_INTERFACE_HELP_URL, icon = UISupport.TOOL_ICON_PATH )
280 	protected interface Form
281 	{
282 		@AField( name = "Definition URL", description = "The URL or file for the updated definition", type = AFieldType.FILE )
283 		public final static String DEFINITION_URL = "Definition URL";
284 
285 		@AField( name = "Create New Requests", description = "Create default requests for new methods", type = AFieldType.BOOLEAN )
286 		public final static String CREATE_REQUESTS = "Create New Requests";
287 
288 		@AField( name = "Recreate Requests", description = "Recreate existing request with the new schema", type = AFieldType.BOOLEAN )
289 		public final static String RECREATE_REQUESTS = "Recreate Requests";
290 
291 		@AField( name = "Recreate Optional", description = "Recreate optional content when updating requests", type = AFieldType.BOOLEAN )
292 		public final static String RECREATE_OPTIONAL = "Recreate Optional";
293 
294 		@AField( name = "Keep Existing", description = "Keeps existing values when recreating requests", type = AFieldType.BOOLEAN )
295 		public final static String KEEP_EXISTING = "Keep Existing";
296 
297 		@AField( name = "Keep SOAP Headers", description = "Keeps any SOAP Headers when recreating requests", type = AFieldType.BOOLEAN )
298 		public final static String KEEP_HEADERS = "Keep SOAP Headers";
299 
300 		@AField( name = "Create Backups", description = "Create backup copies of changed requests", type = AFieldType.BOOLEAN )
301 		public final static String CREATE_BACKUPS = "Create Backups";
302 
303 		@AField( name = "Update TestRequests", description = "Updates all TestRequests for operations in this Interface also", type = AFieldType.BOOLEAN )
304 		public final static String UPDATE_TESTREQUESTS = "Update TestRequests";
305 
306 		@AField( name = "Open Request List", description = "Opens a list of all requests that have been updated", type = AFieldType.BOOLEAN )
307 		public final static String OPEN_LIST = "Open Request List";
308 	}
309 }