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