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.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           // try to allow older namespaces
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 //         URL url = new URL(wadlUrl);
417 //			ApplicationDocument applicationDocument = ApplicationDocument.Factory.parse(url);
418 //			result.put(url.getPath(), applicationDocument);
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 }