1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.teststeps;
14
15 import java.util.ArrayList;
16 import java.util.List;
17
18 import org.apache.log4j.Logger;
19 import org.apache.xmlbeans.XmlObject;
20 import org.w3c.dom.Element;
21 import org.w3c.dom.Node;
22
23 import com.eviware.soapui.config.TestStepConfig;
24 import com.eviware.soapui.config.TransferValuesStepConfig;
25 import com.eviware.soapui.config.ValueTransferConfig;
26 import com.eviware.soapui.impl.wsdl.WsdlTestCase;
27 import com.eviware.soapui.impl.wsdl.WsdlTestStep;
28 import com.eviware.soapui.impl.wsdl.panels.testcase.TransferResponseValuesTestStepPanelBuilder;
29 import com.eviware.soapui.model.PanelBuilder;
30 import com.eviware.soapui.model.testsuite.TestRunner;
31 import com.eviware.soapui.model.testsuite.TestStep;
32 import com.eviware.soapui.support.XmlUtils;
33
34 /***
35 * WsdlTestStep for transferring values from a WsdlTestRequest response to a
36 * WsdlTestRequest request using XPath expressions
37 *
38 * @author Ole.Matzura
39 */
40
41 public class TransferResponseValuesTestStep extends WsdlTestStep
42 {
43 private TransferValuesStepConfig transferStepConfig;
44 private TransferResponseValuesTestStepPanelBuilder panelBuilder;
45 private final static Logger log = Logger.getLogger( TransferResponseValuesTestStep.class );
46 private boolean canceled;
47 private List<ValueTransfer> transfers = new ArrayList<ValueTransfer>();
48
49 public TransferResponseValuesTestStep(WsdlTestCase testCase, TestStepConfig config)
50 {
51 super(testCase, config);
52
53 if( config.getConfig() != null )
54 {
55 transferStepConfig = (TransferValuesStepConfig) config.getConfig().changeType(TransferValuesStepConfig.type);
56 for( int c = 0; c < transferStepConfig.sizeOfTransfersArray(); c++ )
57 {
58 transfers.add( new ValueTransfer( transferStepConfig.getTransfersArray( c )));
59 }
60 }
61 else
62 {
63 transferStepConfig = (TransferValuesStepConfig) config.addNewConfig().changeType( TransferValuesStepConfig.type );
64 }
65 }
66
67 public TransferValuesStepConfig getTransferConfig()
68 {
69 return transferStepConfig;
70 }
71
72 protected void resetConfigOnMove(TestStepConfig config)
73 {
74 super.resetConfigOnMove(config);
75
76 transferStepConfig = (TransferValuesStepConfig) config.getConfig().changeType(TransferValuesStepConfig.type);
77 for( int c = 0; c < transferStepConfig.sizeOfTransfersArray(); c++ )
78 {
79 transfers.get( c ).setConfig( transferStepConfig.getTransfersArray( c ));
80 }
81 }
82
83 public void run( TestRunner runner )
84 {
85 canceled = false;
86
87 int ix = runner.getCurrentStepIndex();
88 if( ix == 0 || ix == runner.getTestCase().getTestStepCount()-1 ) return;
89
90 TestStep previousStep = runner.getTestCase().getTestStepAt( ix-1 );
91 if( !(previousStep instanceof WsdlTestRequestStep )) return;
92
93 TestStep nextStep = runner.getTestCase().getTestStepAt( ix+1 );
94 if( !(nextStep instanceof WsdlTestRequestStep )) return;
95
96 runTransfer( ((WsdlTestRequestStep) previousStep)
97 .getTestRequest(), ((WsdlTestRequestStep) nextStep)
98 .getTestRequest());
99 }
100
101 public void runTransfer( WsdlTestRequest sourceRequest, WsdlTestRequest targetRequest )
102 {
103 ValueTransferConfig[] transfers = transferStepConfig.getTransfersArray();
104 for( int c = 0; c < transfers.length; c++ )
105 {
106 try
107 {
108 if( canceled )
109 return;
110
111 transferValues( sourceRequest, targetRequest, transfers[c]);
112 }
113 catch (Exception e)
114 {
115 log.error( e.getMessage() );
116 e.printStackTrace();
117 }
118 }
119 }
120
121 public void transferValues(WsdlTestRequest sourceRequest, WsdlTestRequest targetRequest, ValueTransferConfig transfer) throws Exception
122 {
123 XmlObject previous = XmlObject.Factory.parse( sourceRequest.getResponseContent());
124 XmlObject[] sourceValues = previous.selectPath( transfer.getSourcePath() );
125 if( sourceValues.length == 0 )
126 {
127 log.info( "No match found for transfer sourcePath [" + transfer.getSourcePath() +
128 "] in transfer [" + transfer.getName() + "]");
129 return;
130 }
131
132 XmlObject next = XmlObject.Factory.parse( targetRequest.getRequestContent());
133 XmlObject[] destValues = next.selectPath( transfer.getTargetPath() );
134 if( destValues.length == 0 )
135 {
136 log.info( "No match found for transfer targetPath [" + transfer.getTargetPath() +
137 "] in transfer [" + transfer.getName() + "]" );
138 return;
139 }
140
141 if( sourceValues.length != destValues.length )
142 throw new Exception( "Number of matching values must be same in source response and destination request" +
143 "; " + sourceValues.length + ":" + destValues.length );
144
145 for( int c = 0; c < sourceValues.length; c++ )
146 {
147 transferValue( sourceValues[c], destValues[c], transfer );
148 }
149
150 if( canceled )
151 return;
152
153 targetRequest.setRequest( next.xmlText() );
154 }
155
156 private void transferValue(XmlObject source, XmlObject dest, ValueTransferConfig transfer) throws Exception
157 {
158
159 Node destNode = dest.getDomNode();
160 Node sourceNode = source.getDomNode();
161 short destNodeType = destNode.getNodeType();
162 short sourceNodeType = sourceNode.getNodeType();
163
164
165 if( destNodeType == sourceNodeType )
166 {
167 dest.set( source.copy() );
168 }
169
170 else if( (sourceNodeType == Node.TEXT_NODE && destNodeType == Node.ATTRIBUTE_NODE) ||
171 (sourceNodeType == Node.ATTRIBUTE_NODE && destNodeType == Node.TEXT_NODE) )
172 {
173 destNode.setNodeValue( sourceNode.getNodeValue() );
174 }
175 else if( sourceNodeType == Node.ELEMENT_NODE &&
176 destNodeType == Node.ATTRIBUTE_NODE || destNodeType == Node.TEXT_NODE )
177 {
178 destNode.setNodeValue( XmlUtils.getElementText( (Element) sourceNode ));
179 }
180 else if( destNodeType == Node.ELEMENT_NODE &&
181 sourceNodeType == Node.ATTRIBUTE_NODE || sourceNodeType == Node.TEXT_NODE )
182 {
183
184 XmlUtils.setElementText( (Element) destNode, sourceNode.getNodeValue() );
185 }
186 }
187
188 public PanelBuilder getPanelBuilder()
189 {
190 if( panelBuilder == null )
191 panelBuilder = new TransferResponseValuesTestStepPanelBuilder( this );
192
193 return panelBuilder;
194 }
195
196 public boolean cancel()
197 {
198 canceled = true;
199 return canceled;
200 }
201
202 public int getTransferCount()
203 {
204 return transferStepConfig.sizeOfTransfersArray();
205 }
206
207 public ValueTransfer getTransferAt( int index )
208 {
209 return transfers.get( index );
210 }
211
212 public ValueTransfer addTransfer( String name )
213 {
214 ValueTransfer transfer = new ValueTransfer( transferStepConfig.addNewTransfers());
215 transfers.add( transfer );
216 return transfer;
217 }
218
219 public void removeTransferAt( int index )
220 {
221 transfers.remove( index );
222 transferStepConfig.removeTransfers( index );
223 }
224
225 public class ValueTransfer
226 {
227 private ValueTransferConfig config;
228
229 private ValueTransfer( ValueTransferConfig config )
230 {
231 this.config = config;
232 }
233
234 private void setConfig(ValueTransferConfig config)
235 {
236 this.config = config;
237 }
238
239 public String getSourcePath()
240 {
241 return config.getSourcePath();
242 }
243
244 public String getTargetPath()
245 {
246 return config.getTargetPath();
247 }
248
249 public String getName()
250 {
251 return config.getName();
252 }
253
254 public void setSourcePath( String path )
255 {
256 config.setSourcePath( path );
257 }
258
259 public void setTargetPath( String path )
260 {
261 config.setTargetPath( path );
262 }
263
264 public void setName( String name )
265 {
266 config.setName( name );
267 }
268 }
269 }