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 				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 		// just copy if nodes are of same type
147 		Node destNode = dest.getDomNode();
148 		Node sourceNode = source.getDomNode();
149 		short destNodeType = destNode.getNodeType();
150 		short sourceNodeType = sourceNode.getNodeType();
151 		
152 		// same type of node?
153 		if( destNodeType == sourceNodeType )
154 		{
155 			dest.set( source.copy() );
156 		}
157 		// text to attribute?
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 			// hmm.. not sure xmlbeans handles this ok
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 }