View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 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.rest.support;
14  
15  import java.io.UnsupportedEncodingException;
16  import java.net.MalformedURLException;
17  import java.net.URL;
18  import java.net.URLDecoder;
19  import java.net.URLEncoder;
20  
21  import org.apache.xmlbeans.XmlBoolean;
22  
23  import com.eviware.soapui.SoapUI;
24  import com.eviware.soapui.impl.rest.RestRequestInterface;
25  import com.eviware.soapui.impl.rest.support.RestParamsPropertyHolder.ParameterStyle;
26  import com.eviware.soapui.model.propertyexpansion.DefaultPropertyExpansionContext;
27  import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
28  import com.eviware.soapui.support.StringUtils;
29  import com.eviware.soapui.support.Tools;
30  import com.eviware.soapui.support.types.StringList;
31  
32  public class RestUtils
33  {
34  	public static String[] extractTemplateParams( String path )
35  	{
36  		if( StringUtils.isNullOrEmpty( path ) )
37  			return new String[0];
38  
39  		StringList result = new StringList();
40  
41  		int ix = path.indexOf( '{' );
42  		while( ix != -1 )
43  		{
44  			int endIx = path.indexOf( '}', ix );
45  			if( endIx == -1 )
46  				break;
47  
48  			if( endIx > ix + 1 && ( ix > 0 && path.charAt( ix - 1 ) != '$' ) )
49  				result.add( path.substring( ix + 1, endIx ) );
50  
51  			ix = path.indexOf( '{', ix + 1 );
52  		}
53  
54  		return result.toStringArray();
55  
56  	}
57  
58  	public static String extractParams( String pathOrEndpoint, RestParamsPropertyHolder params, boolean keepHost )
59  	{
60  		if( StringUtils.isNullOrEmpty( pathOrEndpoint ) )
61  			return "";
62  
63  		String path = pathOrEndpoint;
64  		String queryString = "";
65  		URL url = null;
66  
67  		try
68  		{
69  			url = new URL( pathOrEndpoint );
70  			path = url.getPath();
71  			queryString = url.getQuery();
72  		}
73  		catch( MalformedURLException e )
74  		{
75  			int ix = path.indexOf( '?' );
76  			if( ix >= 0 )
77  			{
78  				queryString = path.substring( ix + 1 );
79  				path = path.substring( 0, ix );
80  			}
81  		}
82  
83  		String[] items = path.split( "/" );
84  
85  		int templateParamCount = 0;
86  		StringBuffer resultPath = new StringBuffer();
87  
88  		for( int i = 0; i < items.length; i++ )
89  		{
90  			String item = items[i];
91  			try
92  			{
93  				if( item.startsWith( "{" ) && item.endsWith( "}" ) )
94  				{
95  					String name = item.substring( 1, item.length() - 1 );
96  					RestParamProperty property = params.getProperty( name );
97  					if( !params.hasProperty( name ) )
98  					{
99  						property = params.addProperty( name );
100 					}
101 
102 					property.setStyle( ParameterStyle.TEMPLATE );
103 					property.setValue( name );
104 					property.setDefaultValue( name );
105 				}
106 				else
107 				{
108 					String[] matrixParams = item.split( ";" );
109 					if( matrixParams.length > 0 )
110 					{
111 						item = matrixParams[0];
112 						for( int c = 1; c < matrixParams.length; c++ )
113 						{
114 							String matrixParam = matrixParams[c];
115 
116 							int ix = matrixParam.indexOf( '=' );
117 							if( ix == -1 )
118 							{
119 								String name = URLDecoder.decode( matrixParam, "Utf-8" );
120 								if( !params.hasProperty( name ) )
121 									params.addProperty( name ).setStyle( ParameterStyle.MATRIX );
122 							}
123 							else
124 							{
125 
126 								String name = URLDecoder.decode( matrixParam.substring( 0, ix ), "Utf-8" );
127 								RestParamProperty property = params.getProperty( name );
128 								if( property == null )
129 								{
130 									property = params.addProperty( name );
131 								}
132 
133 								property.setStyle( ParameterStyle.MATRIX );
134 								property.setValue( URLDecoder.decode( matrixParam.substring( ix + 1 ), "Utf-8" ) );
135 								property.setDefaultValue( URLDecoder.decode( matrixParam.substring( ix + 1 ), "Utf-8" ) );
136 							}
137 						}
138 					}
139 
140 					Integer.parseInt( item );
141 
142 					String name = "param" + templateParamCount++ ;
143 					RestParamProperty property = params.getProperty( name );
144 					if( !params.hasProperty( name ) )
145 					{
146 						property = params.addProperty( name );
147 					}
148 
149 					property.setStyle( ParameterStyle.TEMPLATE );
150 					property.setValue( item );
151 					property.setDefaultValue( item );
152 
153 					item = "{" + property.getName() + "}";
154 				}
155 			}
156 			catch( Exception e )
157 			{
158 			}
159 
160 			if( StringUtils.hasContent( item ) )
161 				resultPath.append( '/' ).append( item );
162 		}
163 
164 		if( StringUtils.hasContent( queryString ) )
165 		{
166 			items = queryString.split( "&" );
167 			for( String item : items )
168 			{
169 				try
170 				{
171 					int ix = item.indexOf( '=' );
172 					if( ix == -1 )
173 					{
174 						String name = URLDecoder.decode( item, "Utf-8" );
175 
176 						if( !params.hasProperty( name ) )
177 						{
178 							params.addProperty( name ).setStyle( ParameterStyle.QUERY );
179 						}
180 					}
181 					else
182 					{
183 						String name = URLDecoder.decode( item.substring( 0, ix ), "Utf-8" );
184 						RestParamProperty property = params.getProperty( name );
185 						if( property == null )
186 						{
187 							property = params.addProperty( name );
188 						}
189 
190 						property.setStyle( ParameterStyle.QUERY );
191 						property.setValue( URLDecoder.decode( item.substring( ix + 1 ), "Utf-8" ) );
192 						property.setDefaultValue( URLDecoder.decode( item.substring( ix + 1 ), "Utf-8" ) );
193 					}
194 				}
195 				catch( UnsupportedEncodingException e )
196 				{
197 					e.printStackTrace();
198 				}
199 			}
200 		}
201 
202 		if( path.endsWith( "/" ) )
203 			resultPath.append( '/' );
204 
205 		if( keepHost && url != null )
206 		{
207 			return Tools.getEndpointFromUrl( url ) + resultPath.toString();
208 		}
209 
210 		return resultPath.toString();
211 	}
212 
213 	@SuppressWarnings("deprecation")
214 	public static String expandPath( String path, RestParamsPropertyHolder params, RestRequestInterface request )
215 	{
216 		StringBuffer query = request.isPostQueryString() || "multipart/form-data".equals( request.getMediaType() ) ? null
217 				: new StringBuffer();
218 		DefaultPropertyExpansionContext context = new DefaultPropertyExpansionContext( request );
219 
220 		for( int c = 0; c < params.getPropertyCount(); c++ )
221 		{
222 			RestParamProperty param = params.getPropertyAt( c );
223 
224 			String value = PropertyExpander.expandProperties( context, param.getValue() );
225 			if( value != null && !param.isDisableUrlEncoding() )
226 			{
227 				try
228 				{
229 					String encoding = System.getProperty( "soapui.request.encoding", request.getEncoding() );
230 
231 					if( StringUtils.hasContent( encoding ) )
232 						value = URLEncoder.encode( value, encoding );
233 					else
234 						value = URLEncoder.encode( value );
235 				}
236 				catch( UnsupportedEncodingException e1 )
237 				{
238 					SoapUI.logError( e1 );
239 					value = URLEncoder.encode( value );
240 				}
241 			}
242 
243 			if( !StringUtils.hasContent( value ) && !param.getRequired() )
244 				continue;
245 
246 			if( value == null )
247 				value = "";
248 			
249 			switch( param.getStyle() )
250 			{
251 			case QUERY :
252 				if( query != null )
253 				{
254 					if( query.length() > 0 )
255 						query.append( '&' );
256 
257 					query.append( URLEncoder.encode( param.getName() ) );
258 					query.append( '=' );
259 
260 					if( StringUtils.hasContent( value ) )
261 						query.append( value );
262 				}
263 				break;
264 			case TEMPLATE :
265 				path = path.replaceAll( "//{" + param.getName() + "//}", value );
266 				break;
267 			case MATRIX :
268 				if( param.getType().equals( XmlBoolean.type.getName() ) )
269 				{
270 					if( value.toUpperCase().equals( "TRUE" ) || value.equals( "1" ) )
271 					{
272 						path += ";" + param.getName();
273 					}
274 				}
275 				else
276 				{
277 					path += ";" + param.getName();
278 					if( StringUtils.hasContent( value ) )
279 					{
280 						path += "=" + value;
281 					}
282 				}
283 			case PLAIN :
284 				break;
285 			}
286 		}
287 
288 		if( query != null && query.length() > 0 )
289 			path += "?" + query.toString();
290 
291 		return path;
292 	}
293 }