View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 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 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           // try to allow older namespaces
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 //         URL url = new URL(wadlUrl);
422 //			ApplicationDocument applicationDocument = ApplicationDocument.Factory.parse(url);
423 //			result.put(url.getPath(), applicationDocument);
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 }