1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.teststeps;
14
15 import org.apache.log4j.Logger;
16 import org.apache.xmlbeans.XmlObject;
17 import org.w3c.dom.Element;
18 import org.w3c.dom.Node;
19
20 import com.eviware.soapui.config.TestStepConfig;
21 import com.eviware.soapui.config.TransferValuesStepConfig;
22 import com.eviware.soapui.config.ValueTransferConfig;
23 import com.eviware.soapui.impl.wsdl.WsdlTestCase;
24 import com.eviware.soapui.impl.wsdl.WsdlTestStep;
25 import com.eviware.soapui.impl.wsdl.panels.testcase.TransferResponseValuesTestStepPanelBuilder;
26 import com.eviware.soapui.model.PanelBuilder;
27 import com.eviware.soapui.model.testsuite.TestRunner;
28 import com.eviware.soapui.model.testsuite.TestStep;
29 import com.eviware.soapui.support.XmlUtils;
30
31 /***
32 * WsdlTestStep for transferring values from a WsdlTestRequest response to a
33 * WsdlTestRequest request using XPath expressions
34 *
35 * @author Ole.Matzura
36 */
37
38 public class TransferResponseValuesTestStep extends WsdlTestStep
39 {
40 private TransferValuesStepConfig transferStepConfig;
41 private TransferResponseValuesTestStepPanelBuilder panelBuilder;
42 private final static Logger log = Logger.getLogger( TransferResponseValuesTestStep.class );
43 private boolean canceled;
44
45 public TransferResponseValuesTestStep(WsdlTestCase testCase, TestStepConfig config)
46 {
47 super(testCase, config);
48
49 if( config.getConfig() != null )
50 {
51 transferStepConfig = (TransferValuesStepConfig) config.getConfig().changeType(TransferValuesStepConfig.type);
52 }
53 else
54 {
55 transferStepConfig = (TransferValuesStepConfig) config.addNewConfig().changeType( TransferValuesStepConfig.type );
56 }
57 }
58
59 public TransferValuesStepConfig getTransferConfig()
60 {
61 return transferStepConfig;
62 }
63
64 protected void resetConfigOnMove(TestStepConfig config)
65 {
66 super.resetConfigOnMove(config);
67
68 transferStepConfig = (TransferValuesStepConfig) config.getConfig().changeType(TransferValuesStepConfig.type);
69 }
70
71 public void run( TestRunner runner )
72 {
73 canceled = false;
74
75 int ix = runner.getCurrentStepIndex();
76 if( ix == 0 || ix == runner.getTestCase().getTestStepCount()-1 ) return;
77
78 TestStep previousStep = runner.getTestCase().getTestStepAt( ix-1 );
79 if( !(previousStep instanceof WsdlTestRequestStep )) return;
80
81 TestStep nextStep = runner.getTestCase().getTestStepAt( ix+1 );
82 if( !(nextStep instanceof WsdlTestRequestStep )) return;
83
84 runTransfer( ((WsdlTestRequestStep) previousStep)
85 .getTestRequest(), ((WsdlTestRequestStep) nextStep)
86 .getTestRequest());
87 }
88
89 public void runTransfer( WsdlTestRequest sourceRequest, WsdlTestRequest targetRequest )
90 {
91 ValueTransferConfig[] transfers = transferStepConfig.getTransfersArray();
92 for( int c = 0; c < transfers.length; c++ )
93 {
94 try
95 {
96 if( canceled )
97 return;
98
99 transferValues( sourceRequest, targetRequest, transfers[c]);
100 }
101 catch (Exception e)
102 {
103 log.error( e.getMessage() );
104 e.printStackTrace();
105 }
106 }
107 }
108
109 public void transferValues(WsdlTestRequest sourceRequest, WsdlTestRequest targetRequest, ValueTransferConfig transfer) throws Exception
110 {
111 XmlObject previous = XmlObject.Factory.parse( sourceRequest.getResponseContent());
112 XmlObject[] sourceValues = previous.selectPath( transfer.getSourcePath() );
113 if( sourceValues.length == 0 )
114 {
115 log.info( "No match found for transfer sourcePath [" + transfer.getSourcePath() +
116 "] in transfer [" + transfer.getName() + "]");
117 return;
118 }
119
120 XmlObject next = XmlObject.Factory.parse( targetRequest.getRequestContent());
121 XmlObject[] destValues = next.selectPath( transfer.getTargetPath() );
122 if( destValues.length == 0 )
123 {
124 log.info( "No match found for transfer targetPath [" + transfer.getTargetPath() +
125 "] in transfer [" + transfer.getName() + "]" );
126 return;
127 }
128
129 if( sourceValues.length != destValues.length )
130 throw new Exception( "Number of matching values must be same in source response and destination request" +
131 "; " + sourceValues.length + ":" + destValues.length );
132
133 for( int c = 0; c < sourceValues.length; c++ )
134 {
135 transferValue( sourceValues[c], destValues[c], transfer );
136 }
137
138 if( canceled )
139 return;
140
141 targetRequest.setRequest( next.xmlText() );
142 }
143
144 private void transferValue(XmlObject source, XmlObject dest, ValueTransferConfig transfer) throws Exception
145 {
146
147 Node destNode = dest.getDomNode();
148 Node sourceNode = source.getDomNode();
149 short destNodeType = destNode.getNodeType();
150 short sourceNodeType = sourceNode.getNodeType();
151
152
153 if( destNodeType == sourceNodeType )
154 {
155 dest.set( source.copy() );
156 }
157
158 else if( (sourceNodeType == Node.TEXT_NODE && destNodeType == Node.ATTRIBUTE_NODE) ||
159 (sourceNodeType == Node.ATTRIBUTE_NODE && destNodeType == Node.TEXT_NODE) )
160 {
161 destNode.setNodeValue( sourceNode.getNodeValue() );
162 }
163 else if( sourceNodeType == Node.ELEMENT_NODE &&
164 destNodeType == Node.ATTRIBUTE_NODE || destNodeType == Node.TEXT_NODE )
165 {
166 destNode.setNodeValue( XmlUtils.getElementText( (Element) sourceNode ));
167 }
168 else if( destNodeType == Node.ELEMENT_NODE &&
169 sourceNodeType == Node.ATTRIBUTE_NODE || sourceNodeType == Node.TEXT_NODE )
170 {
171
172 XmlUtils.setElementText( (Element) destNode, sourceNode.getNodeValue() );
173 }
174 }
175
176 public PanelBuilder getPanelBuilder()
177 {
178 if( panelBuilder == null )
179 panelBuilder = new TransferResponseValuesTestStepPanelBuilder( this );
180
181 return panelBuilder;
182 }
183
184 public boolean cancel()
185 {
186 canceled = true;
187 return canceled;
188 }
189 }