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