1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.rest.support;
14
15 import com.eviware.soapui.impl.rest.RestRepresentation;
16 import com.eviware.soapui.impl.rest.RestRequest;
17 import com.eviware.soapui.impl.rest.RestResource;
18 import com.eviware.soapui.impl.rest.RestService;
19 import com.eviware.soapui.impl.rest.support.XmlBeansRestParamsTestPropertyHolder.ParameterStyle;
20 import com.eviware.soapui.impl.rest.support.XmlBeansRestParamsTestPropertyHolder.RestParamProperty;
21 import com.eviware.soapui.impl.wsdl.support.Constants;
22 import com.eviware.soapui.impl.wsdl.support.UrlSchemaLoader;
23 import com.eviware.soapui.impl.wsdl.support.xsd.SchemaUtils;
24 import com.eviware.soapui.support.StringUtils;
25 import com.eviware.soapui.support.Tools;
26 import com.eviware.soapui.support.UISupport;
27 import com.sun.research.wadl.x2006.x10.ApplicationDocument;
28 import com.sun.research.wadl.x2006.x10.ApplicationDocument.Application;
29 import com.sun.research.wadl.x2006.x10.DocDocument.Doc;
30 import com.sun.research.wadl.x2006.x10.MethodDocument.Method;
31 import com.sun.research.wadl.x2006.x10.ParamDocument.Param;
32 import com.sun.research.wadl.x2006.x10.RepresentationType;
33 import com.sun.research.wadl.x2006.x10.ResourceDocument.Resource;
34 import com.sun.research.wadl.x2006.x10.ResourceTypeDocument;
35 import com.sun.research.wadl.x2006.x10.ParamStyle;
36 import com.sun.research.wadl.x2006.x10.ResourcesDocument.Resources;
37 import org.apache.xmlbeans.XmlException;
38 import org.apache.xmlbeans.XmlObject;
39 import org.w3c.dom.Document;
40 import org.w3c.dom.Element;
41
42 import java.io.IOException;
43 import java.io.UnsupportedEncodingException;
44 import java.net.URI;
45 import java.net.URISyntaxException;
46 import java.net.URL;
47 import java.net.URLDecoder;
48 import java.util.HashMap;
49 import java.util.List;
50 import java.util.Map;
51
52 public class WadlImporter
53 {
54 private RestService service;
55 private Application application;
56 private Resources resources;
57 private Map<String, ApplicationDocument> refCache = new HashMap<String, ApplicationDocument>();
58
59 public WadlImporter( RestService service )
60 {
61 this.service = service;
62 }
63
64 public void initFromWadl( String wadlUrl )
65 {
66 try
67 {
68 XmlObject xmlObject = XmlObject.Factory.parse( new URL( wadlUrl ) );
69
70 Element element = ( ( Document ) xmlObject.getDomNode() ).getDocumentElement();
71
72
73 if( element.getLocalName().equals( "application" ) && element.getNamespaceURI().startsWith( "http://research.sun.com/wadl" ) &&
74 !element.getNamespaceURI().equals( Constants.WADL10_NS ) )
75 {
76 String content = xmlObject.xmlText();
77 content = content.replaceAll( "\"" + element.getNamespaceURI() + "\"", "\"" + Constants.WADL10_NS + "\"" );
78 xmlObject = ApplicationDocument.Factory.parse( content );
79 }
80 else if( !element.getLocalName().equals( "application" ) || !element.getNamespaceURI().equals( Constants.WADL10_NS ) )
81 {
82 throw new Exception( "Document is not a WADL application with " + Constants.WADL10_NS + " namespace" );
83 }
84
85 ApplicationDocument applicationDocument = ( ApplicationDocument ) xmlObject.changeType( ApplicationDocument.type );
86 application = applicationDocument.getApplication();
87
88 resources = application.getResources();
89
90 service.setName( getFirstTitle( application.getDocList(), service.getName() ) );
91
92 String base = resources.getBase();
93
94 try
95 {
96 URL baseUrl = new URL( base );
97 service.setBasePath( baseUrl.getPath() );
98
99 service.addEndpoint( Tools.getEndpointFromUrl( baseUrl ) );
100 }
101 catch( Exception e )
102 {
103 service.setBasePath( base );
104 }
105
106 service.setWadlUrl( wadlUrl );
107
108 for( Resource resource : resources.getResourceList() )
109 {
110 String name = getFirstTitle( resource.getDocList(), resource.getPath() );
111 String path = resource.getPath();
112
113 RestResource newResource = service.addNewResource( name, path );
114 initResourceFromWadlResource( newResource, resource );
115
116 addSubResources( newResource, resource );
117 }
118 }
119 catch( Exception e )
120 {
121 UISupport.showErrorMessage( e );
122 }
123 }
124
125 private void addSubResources( RestResource newResource, Resource resource )
126 {
127 for( Resource res : resource.getResourceList() )
128 {
129 String name = getFirstTitle( res.getDocList(), res.getPath() );
130 String path = res.getPath();
131
132 RestResource newRes = newResource.addNewChildResource( name, path );
133 initResourceFromWadlResource( newRes, res );
134
135 addSubResources( newRes, res );
136 }
137 }
138
139 private String getFirstTitle( List<Doc> list, String defaultTitle )
140 {
141 for( Doc doc : list )
142 {
143 if( StringUtils.hasContent( doc.getTitle() ) )
144 {
145 return doc.getTitle();
146 }
147 }
148 return defaultTitle;
149 }
150
151 private void initResourceFromWadlResource( RestResource newResource, Resource resource )
152 {
153 for( Param param : resource.getParamList() )
154 {
155 String nm = param.getName();
156 RestParamProperty prop = newResource.hasProperty( nm ) ?
157 newResource.getProperty( nm ) : newResource.addProperty( nm );
158
159 initParam( param, prop );
160 }
161
162 for( Method method : resource.getMethodList() )
163 {
164 method = resolveMethod( method );
165 initMethod( newResource, method );
166 }
167
168 List types = resource.getType();
169 if( types != null && types.size() > 0 )
170 {
171 for( Object obj : types )
172 {
173 ResourceTypeDocument.ResourceType type = resolveResource( obj.toString() );
174 if( type != null )
175 {
176 for( Method method : type.getMethodList() )
177 {
178 method = resolveMethod( method );
179 RestRequest restRequest = initMethod( newResource, method );
180
181 for( Param param : type.getParamList() )
182 {
183 String nm = param.getName();
184 RestParamProperty prop = restRequest.hasProperty( nm ) ?
185 restRequest.getProperty( nm ) : restRequest.addProperty( nm );
186
187 initParam( param, prop );
188 }
189 }
190 }
191 }
192 }
193 }
194
195 private RestRequest initMethod( RestResource newResource, Method method )
196 {
197 String name = method.getName();
198 if( StringUtils.hasContent( method.getId() ) )
199 name += " - " + method.getId();
200
201 RestRequest request = newResource.addNewRequest( getFirstTitle( method.getDocList(), name ) );
202 request.setMethod( RestRequest.RequestMethod.valueOf( method.getName() ) );
203
204 if( method.getRequest() != null )
205 {
206 for( Param param : method.getRequest().getParamList() )
207 {
208 RestParamProperty p = request.addProperty( param.getName() );
209 initParam( param, p );
210 }
211
212 for( RepresentationType representationType : method.getResponse().getRepresentationList() )
213 {
214 representationType = resolveRepresentation( representationType );
215 addRepresentationFromConfig( request, representationType, RestRepresentation.Type.REQUEST );
216 }
217 }
218
219 if( method.getResponse() != null )
220 {
221 for( RepresentationType representationType : method.getResponse().getRepresentationList() )
222 {
223 representationType = resolveRepresentation( representationType );
224 addRepresentationFromConfig( request, representationType, RestRepresentation.Type.RESPONSE );
225 }
226
227 for( RepresentationType representationType : method.getResponse().getFaultList() )
228 {
229 representationType = resolveFault( representationType );
230 addRepresentationFromConfig( request, representationType, RestRepresentation.Type.FAULT );
231 }
232 }
233
234 return request;
235 }
236
237 private void addRepresentationFromConfig( RestRequest request, RepresentationType representationType, RestRepresentation.Type type )
238 {
239 RestRepresentation restRepresentation = request.addNewRepresentation( type );
240 restRepresentation.setMediaType( representationType.getMediaType() );
241 restRepresentation.setElement( representationType.getElement() );
242 restRepresentation.setStatus( representationType.getStatus() );
243 restRepresentation.setId( representationType.getId() );
244 restRepresentation.setDescription( getFirstTitle( representationType.getDocList(), null ) );
245 }
246
247 private void initParam( Param param, RestParamProperty prop )
248 {
249 prop.setDefaultValue( param.getDefault() );
250 prop.setValue( param.getDefault() );
251 ParamStyle.Enum paramStyle = param.getStyle();
252 if( paramStyle == null )
253 paramStyle = ParamStyle.QUERY;
254
255 prop.setStyle( ParameterStyle.valueOf( paramStyle.toString().toUpperCase() ) );
256 prop.setRequired( param.getRequired() );
257 prop.setType( param.getType() );
258
259 String[] options = new String[param.sizeOfOptionArray()];
260 for( int c = 0; c < options.length; c++ )
261 options[c] = param.getOptionArray( c ).getValue();
262
263 if( options.length > 0 )
264 prop.setOptions( options );
265 }
266
267 private Method resolveMethod( Method method )
268 {
269 String href = method.getHref();
270 if( !StringUtils.hasContent( href ) )
271 return method;
272
273 for( Method m : application.getMethodList() )
274 {
275 if( m.getId().equals( href.substring( 1 ) ) )
276 return m;
277 }
278
279 try
280 {
281 ApplicationDocument applicationDocument = loadReferencedWadl( href );
282 if( applicationDocument != null )
283 {
284 int ix = href.lastIndexOf( '#' );
285 if( ix > 0 )
286 href = href.substring( ix + 1 );
287
288 for( Method m : application.getMethodList() )
289 {
290 if( m.getId().equals( href ) )
291 return m;
292 }
293 }
294 }
295 catch( Exception e )
296 {
297 e.printStackTrace();
298 }
299
300 return method;
301 }
302
303 private RepresentationType resolveRepresentation( RepresentationType representation )
304 {
305 String href = representation.getHref();
306 if( !StringUtils.hasContent( href ) )
307 return representation;
308
309 try
310 {
311 ApplicationDocument applicationDocument = loadReferencedWadl( href );
312 if( applicationDocument != null )
313 {
314 int ix = href.lastIndexOf( '#' );
315 if( ix > 0 )
316 href = href.substring( ix + 1 );
317
318 for( RepresentationType m : application.getRepresentationList() )
319 {
320 if( m.getId().equals( href ) )
321 return m;
322 }
323 }
324 }
325 catch( Exception e )
326 {
327 e.printStackTrace();
328 }
329
330 return representation;
331 }
332
333 private RepresentationType resolveFault( RepresentationType representation )
334 {
335 String href = representation.getHref();
336 if( !StringUtils.hasContent( href ) )
337 return representation;
338
339 try
340 {
341 ApplicationDocument applicationDocument = loadReferencedWadl( href );
342 if( applicationDocument != null )
343 {
344 int ix = href.lastIndexOf( '#' );
345 if( ix > 0 )
346 href = href.substring( ix + 1 );
347
348 for( RepresentationType m : application.getFaultList() )
349 {
350 if( m.getId().equals( href ) )
351 return m;
352 }
353 }
354 }
355 catch( Exception e )
356 {
357 e.printStackTrace();
358 }
359
360 return representation;
361 }
362
363 private ResourceTypeDocument.ResourceType resolveResource( String id )
364 {
365 for( ResourceTypeDocument.ResourceType resourceType : application.getResourceTypeList() )
366 {
367 if( resourceType.getId().equals( id ) )
368 return resourceType;
369 }
370
371 try
372 {
373 ApplicationDocument applicationDocument = loadReferencedWadl( id );
374 if( applicationDocument != null )
375 {
376 int ix = id.lastIndexOf( '#' );
377 if( ix > 0 )
378 id = id.substring( ix + 1 );
379
380 for( ResourceTypeDocument.ResourceType resourceType : applicationDocument.getApplication().getResourceTypeList() )
381 {
382 if( resourceType.getId().equals( id ) )
383 return resourceType;
384 }
385 }
386 }
387 catch( Exception e )
388 {
389 e.printStackTrace();
390 }
391
392 return null;
393 }
394
395 private ApplicationDocument loadReferencedWadl( String id )
396 throws URISyntaxException, XmlException, IOException
397 {
398 int ix = id.indexOf( '#' );
399 if( ix != -1 )
400 id = id.substring( 0, ix );
401 ApplicationDocument applicationDocument = refCache.get( id );
402
403 if( applicationDocument == null )
404 {
405 URI uri = new URI( id );
406 applicationDocument = ApplicationDocument.Factory.parse( uri.toURL() );
407 refCache.put( id, applicationDocument );
408 }
409
410 return applicationDocument;
411 }
412
413 public static Map<String, XmlObject> getDefinitionParts( String wadlUrl )
414 {
415 Map<String, XmlObject> result = new HashMap<String, XmlObject>();
416
417 try
418 {
419 return SchemaUtils.getSchemas( wadlUrl, new UrlSchemaLoader( wadlUrl ) );
420
421
422
423
424 }
425 catch( Exception e )
426 {
427 e.printStackTrace();
428 }
429
430 return result;
431 }
432
433 public static String extractParams( URL param, XmlBeansRestParamsTestPropertyHolder params )
434 {
435 String path = param.getPath();
436 String[] items = path.split( "/" );
437
438 int templateParamCount = 0;
439 StringBuffer resultPath = new StringBuffer();
440
441 for( int i = 0; i < items.length; i++ )
442 {
443 String item = items[i];
444 try
445 {
446 String[] matrixParams = item.split( ";" );
447 if( matrixParams.length > 0 )
448 {
449 item = matrixParams[0];
450 for( int c = 1; c < matrixParams.length; c++ )
451 {
452 String matrixParam = matrixParams[c];
453
454 int ix = matrixParam.indexOf( '=' );
455 if( ix == -1 )
456 {
457 params.addProperty( URLDecoder.decode( matrixParam, "Utf-8" ) ).setStyle( ParameterStyle.MATRIX );
458 }
459 else
460 {
461 String name = matrixParam.substring( 0, ix );
462 RestParamProperty property = params.addProperty( URLDecoder.decode( name, "Utf-8" ) );
463 property.setStyle( ParameterStyle.MATRIX );
464 property.setValue( URLDecoder.decode( matrixParam.substring( ix + 1 ), "Utf-8" ) );
465 }
466 }
467 }
468
469 Integer.parseInt( item );
470 RestParamProperty prop = params.addProperty( "param" + templateParamCount++ );
471 prop.setStyle( ParameterStyle.TEMPLATE );
472 prop.setValue( item );
473
474 item = "{" + prop.getName() + "}";
475 }
476 catch( Exception e )
477 {
478 }
479
480 if( StringUtils.hasContent( item ) )
481 resultPath.append( '/' ).append( item );
482 }
483
484 String query = ( ( URL ) param ).getQuery();
485 if( StringUtils.hasContent( query ) )
486 {
487 items = query.split( "&" );
488 for( String item : items )
489 {
490 try
491 {
492 int ix = item.indexOf( '=' );
493 if( ix == -1 )
494 {
495 params.addProperty( URLDecoder.decode( item, "Utf-8" ) ).setStyle( ParameterStyle.QUERY );
496 }
497 else
498 {
499 String name = item.substring( 0, ix );
500 RestParamProperty property = params.addProperty( URLDecoder.decode( name, "Utf-8" ) );
501 property.setStyle( ParameterStyle.QUERY );
502 property.setValue( URLDecoder.decode( item.substring( ix + 1 ), "Utf-8" ) );
503 }
504 }
505 catch( UnsupportedEncodingException e )
506 {
507 e.printStackTrace();
508 }
509 }
510 }
511
512 return resultPath.toString();
513 }
514 }