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