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 }