View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 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.submit.filters;
14  
15  import org.apache.log4j.Logger;
16  import org.apache.log4j.Priority;
17  import org.apache.xmlbeans.XmlObject;
18  
19  import com.eviware.soapui.SoapUI;
20  import com.eviware.soapui.impl.wsdl.WsdlRequest;
21  import com.eviware.soapui.impl.wsdl.submit.RequestFilter;
22  import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
23  import com.eviware.soapui.model.iface.SubmitContext;
24  import com.eviware.soapui.model.testsuite.TestRunContext;
25  import com.eviware.soapui.support.xml.XmlUtils;
26  
27  /***
28   * RequestFilter that expands properties in request content
29   * 
30   * @author Ole.Matzura
31   */
32  
33  public class PropertyExpansionRequestFilter implements RequestFilter
34  {
35  	private static final char PROPERTY_SEPARATOR = '#';
36  	private final static Logger log = Logger.getLogger(PropertyExpansionRequestFilter.class);
37  	
38  	public void filterRequest(SubmitContext context, WsdlRequest wsdlRequest)
39  	{
40  		String content = (String) context.getProperty( BaseHttpRequestTransport.REQUEST_CONTENT );
41  		if( content == null )
42  		{
43  			log.warn( "Missing request content in context, skipping property expansion" );
44  		}
45  		else
46  		{
47  			content = expandProperties(context, content);
48  			if( content != null )
49  				context.setProperty( BaseHttpRequestTransport.REQUEST_CONTENT, content );
50  		}
51  	}
52  
53  	@SuppressWarnings("deprecation")
54  	public static String expandProperties(SubmitContext context, String content)
55  	{
56  		int ix = content.indexOf( "${" );
57  		if( ix == -1 )
58  			return content;
59  		
60  		StringBuffer buf = new StringBuffer();
61  		int lastIx = 0;
62  		while( ix != -1 )
63  		{
64  			if( ix > lastIx )
65  			   buf.append( content.substring( lastIx, ix ));
66  			
67  			int ix2 = content.indexOf( '}', ix+2 );
68  			if( ix2 == -1 )
69  				break;
70  
71  			// check for nesting
72  			int ix3 = content.lastIndexOf( "${", ix2 );
73  			if( ix3 != ix )
74  			{
75  				//buf.append( content.substring( ix, ix3 ));
76  				content = content.substring( 0, ix3 ) + expandProperties( context, content.substring( ix3, ix2+1 )) + 
77  				          content.substring( ix2+1 );
78  				
79  				lastIx = ix;
80  				continue;
81  			}
82  			
83  			String propertyName = content.substring( ix+2, ix2 );
84  			Object property = context.getProperty( propertyName );
85  			if( property != null )
86  			{
87  				String value = property.toString();
88  				if( !content.equals( value ))
89  					value = expandProperties( context, value );
90  				
91  				buf.append( value );
92  			}
93  			else if( context instanceof TestRunContext )
94  			{
95  				int sepIx = propertyName.indexOf( PROPERTY_SEPARATOR );
96  				if( sepIx >= 0 )
97  				{
98  					String step = propertyName.substring( 0, sepIx );
99  					String name = propertyName.substring( sepIx+1 );
100 					
101 					sepIx = name.indexOf( PROPERTY_SEPARATOR );
102 					if( sepIx != -1 )
103 					{
104 						String xpath = name.substring( sepIx+1 );
105 						name = name.substring( 0, sepIx );
106 						
107 						if( step.length() == 0 )
108 							property = ((TestRunContext)context).getProperty( name);
109 						else
110 							property = ((TestRunContext)context).getProperty( step, name);
111 						
112 						if( property != null )
113 						{
114 							property = extractXPathPropertyValue( property, xpath );
115 						}
116 					}
117 					else
118 					{
119 						if( step.length() == 0 )
120 							property = ((TestRunContext)context).getProperty( name);
121 						else
122 							property = ((TestRunContext)context).getProperty( step, name);
123 					}
124 					
125 					if( property != null )
126 					{
127 						String value = property.toString();
128 						if( !content.equals( value ))
129 							value = expandProperties( context, value );
130 						
131 						buf.append( value );
132 					}
133 				}
134 			}
135 			else if( propertyName.charAt( 0 ) == PROPERTY_SEPARATOR  )
136 			{
137 				int sepIx = propertyName.indexOf( PROPERTY_SEPARATOR, 1 );
138 				if( sepIx > 0 )
139 				{
140 					String xpath = propertyName.substring( sepIx+1 );
141 					propertyName = propertyName.substring( 1, sepIx );
142 					
143 					property = context.getProperty( propertyName );
144 					if( property != null )
145 					{
146 						property = extractXPathPropertyValue( property, expandProperties( context, xpath ));
147 					}
148 				}
149 				else
150 				{
151 					property = context.getProperty( propertyName.substring( 1 ) );
152 				}
153 				
154 				if( property != null )
155 				{
156 					String value = property.toString();
157 					if( !content.equals( value ))
158 						value = expandProperties( context, value );
159 					
160 					buf.append( value );
161 				}
162 			}
163 				
164 			if( property == null )
165 			{
166 				if( log.isEnabledFor( Priority.WARN ))
167 					log.warn( "Missing property value for [" + propertyName + "]" );
168 				
169 			   buf.append( "${" ).append( propertyName ).append( '}' );
170 			}
171 			
172 			lastIx = ix2+1;
173 			ix = content.indexOf( "${", lastIx );
174 		}
175 		
176 		if( lastIx < content.length() )
177 			buf.append( content.substring( lastIx ));
178 		
179 		return buf.toString();
180 	}
181 
182 	public static String extractXPathPropertyValue( Object property, String xpath )
183 	{
184 		try
185 		{
186 			XmlObject xmlObject = XmlObject.Factory.parse(  property.toString() );
187 			String ns = XmlUtils.declareXPathNamespaces( xmlObject );
188 			XmlObject[] paths = xmlObject.selectPath( ns + xpath );
189 			if( paths.length > 0 )
190 				return XmlUtils.getNodeValue( paths[0].getDomNode() );
191 		}
192 		catch( Exception e )
193 		{
194 			SoapUI.logError( e );
195 		}
196 		
197 		return null;
198 	}
199 }