View Javadoc

1   /*
2    *  soapui, copyright (C) 2005 Ole Matzura / eviware.com 
3    *
4    *  SoapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of the GNU Lesser General Public License as published by the Free Software Foundation; 
6    *  either version 2.1 of the License, or (at your option) any later version.
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.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 				e.printStackTrace();
104 			}
105 		}
106 	}
107 
108 	public void transferValues(WsdlTestRequest sourceRequest, WsdlTestRequest targetRequest, ValueTransferConfig transfer) throws Exception
109 	{
110 		XmlObject previous = XmlObject.Factory.parse( sourceRequest.getResponseContent());
111 		XmlObject[] sourceValues = previous.selectPath( transfer.getSourcePath() );
112 		if( sourceValues.length == 0 ) 
113 		{
114 			log.info( "No match found for transfer sourcePath [" + transfer.getSourcePath() + 
115 					"] in transfer [" + transfer.getName() + "]");
116 			return;
117 		}
118 
119 		XmlObject next = XmlObject.Factory.parse( targetRequest.getRequestContent());
120 	   XmlObject[] destValues = next.selectPath( transfer.getTargetPath() );
121 	   if( destValues.length == 0 ) 
122 	   {
123 			log.info( "No match found for transfer targetPath [" + transfer.getTargetPath() + 
124 					"] in transfer [" + transfer.getName() + "]" );
125 			return;
126 		}
127 	   
128 	   if( sourceValues.length != destValues.length )
129 	   	throw new Exception( "Number of matching values must be same in source response and destination request" );
130 	   
131 	   for( int c = 0; c < sourceValues.length; c++ )
132 	   {
133 	   	transferValue( sourceValues[c], destValues[c], transfer );
134 	   }
135 	   
136 	   if( canceled ) 
137 			return;
138 	   
139 	   targetRequest.setRequest( next.xmlText() );
140 	}
141 
142 	private void transferValue(XmlObject source, XmlObject dest, ValueTransferConfig transfer) throws Exception
143 	{
144 		// just copy if nodes are of same type
145 		Node destNode = dest.getDomNode();
146 		Node sourceNode = source.getDomNode();
147 		short destNodeType = destNode.getNodeType();
148 		short sourceNodeType = sourceNode.getNodeType();
149 		
150 		// same type of node?
151 		if( destNodeType == sourceNodeType )
152 		{
153 			dest.set( source.copy() );
154 		}
155 		// text to attribute?
156 		else if( (sourceNodeType == Node.TEXT_NODE && destNodeType == Node.ATTRIBUTE_NODE) ||
157 				(sourceNodeType == Node.ATTRIBUTE_NODE && destNodeType == Node.TEXT_NODE) )
158 		{
159 			destNode.setNodeValue( sourceNode.getNodeValue() );
160 		}
161 		else if( sourceNodeType == Node.ELEMENT_NODE && 
162 				destNodeType == Node.ATTRIBUTE_NODE || destNodeType == Node.TEXT_NODE )
163 		{
164 			destNode.setNodeValue( XmlUtils.getElementText( (Element) sourceNode ));
165 		}
166 		else if( destNodeType == Node.ELEMENT_NODE && 
167 				sourceNodeType == Node.ATTRIBUTE_NODE || sourceNodeType == Node.TEXT_NODE )
168 		{
169 			// hmm.. not sure xmlbeans handles this ok
170 			XmlUtils.setElementText( (Element) destNode, sourceNode.getNodeValue() );
171 		}
172 	}
173 
174 	public PanelBuilder getPanelBuilder()
175 	{
176 		if( panelBuilder == null )
177 			panelBuilder = new TransferResponseValuesTestStepPanelBuilder( this );
178 		
179 		return panelBuilder;
180 	}
181 
182 	public boolean cancel()
183 	{
184 		canceled = true;
185 		return canceled;
186 	}
187 }