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