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.support.definition.export;
14  
15  import com.eviware.soapui.impl.support.definition.InterfaceDefinition;
16  import com.eviware.soapui.impl.support.definition.InterfaceDefinitionPart;
17  import com.eviware.soapui.impl.wsdl.support.Constants;
18  import com.eviware.soapui.model.iface.Interface;
19  import com.eviware.soapui.support.Tools;
20  import com.eviware.soapui.support.types.StringToStringMap;
21  import org.apache.xmlbeans.SimpleValue;
22  import org.apache.xmlbeans.XmlObject;
23  
24  import java.io.File;
25  import java.net.MalformedURLException;
26  import java.net.URL;
27  import java.util.HashMap;
28  import java.util.List;
29  import java.util.Map;
30  
31  public abstract class AbstractDefinitionExporter<T extends Interface> implements DefinitionExporter
32  {
33     private InterfaceDefinition definition;
34  
35     public AbstractDefinitionExporter( InterfaceDefinition<T> definition )
36     {
37        this.definition = definition;
38     }
39  
40     public InterfaceDefinition<T> getDefinition()
41     {
42        return definition;
43     }
44  
45     public void setDefinition( InterfaceDefinition definition )
46     {
47        this.definition = definition;
48     }
49  
50     public String export( String folderName ) throws Exception
51     {
52        if( definition.getDefinitionCache() == null || !definition.getDefinitionCache().validate() )
53           throw new Exception( "Definition is not cached for export" );
54  
55        File outFolder = new File( folderName );
56        if( !outFolder.exists() && !outFolder.mkdirs() )
57           throw new Exception( "Failed to create directory [" + folderName + "]" );
58  
59        Map<String, String> urlToFileMap = new HashMap<String, String>();
60  
61        setFilenameForPart( definition.getDefinitionCache().getRootPart(), urlToFileMap, null );
62  
63        List<InterfaceDefinitionPart> partList = definition.getDefinitionCache().getDefinitionParts();
64        for( InterfaceDefinitionPart part : partList )
65        {
66           setFilenameForPart( part, urlToFileMap, null );
67        }
68  
69        for( InterfaceDefinitionPart part : partList )
70        {
71           XmlObject obj = XmlObject.Factory.parse( part.getContent() );
72           replaceImportsAndIncludes( obj, urlToFileMap, part.getUrl() );
73           obj.save( new File( outFolder, urlToFileMap.get( part.getUrl() ) ) );
74        }
75  
76        return folderName + File.separatorChar + urlToFileMap.get( definition.getDefinitionCache().getRootPart().getUrl() );
77     }
78  
79     public StringToStringMap createFilesForExport( String urlPrefix ) throws Exception
80     {
81        StringToStringMap result = new StringToStringMap();
82        Map<String, String> urlToFileMap = new HashMap<String, String>();
83  
84        if( urlPrefix == null )
85           urlPrefix = "";
86  
87        setFilenameForPart( definition.getDefinitionCache().getRootPart(), urlToFileMap, urlPrefix );
88  
89        List<InterfaceDefinitionPart> partList = definition.getDefinitionCache().getDefinitionParts();
90        for( InterfaceDefinitionPart part : partList )
91        {
92           if( !part.isRootPart() )
93              setFilenameForPart( part, urlToFileMap, urlPrefix );
94        }
95  
96        for( InterfaceDefinitionPart part : partList )
97        {
98           XmlObject obj = XmlObject.Factory.parse( part.getContent() );
99           replaceImportsAndIncludes( obj, urlToFileMap, part.getUrl() );
100          String urlString = urlToFileMap.get( part.getUrl() );
101          if( urlString.startsWith( urlPrefix ) )
102             urlString = urlString.substring( urlPrefix.length() );
103 
104          result.put( urlString, obj.xmlText() );
105 
106          if( part.isRootPart() )
107             result.put( "#root#", urlString );
108       }
109 
110       return result;
111    }
112 
113    private void setFilenameForPart( InterfaceDefinitionPart part, Map<String, String> urlToFileMap, String urlPrefix )
114            throws MalformedURLException
115    {
116 
117       String path = part.getUrl();
118 
119       try
120       {
121          URL url = new URL( path );
122          path = url.getPath();
123       }
124       catch( MalformedURLException e )
125       {
126       }
127 
128       int ix = path.lastIndexOf( '/' );
129       String fileName = ix == -1 ? path : path.substring( ix + 1 );
130 
131       ix = fileName.lastIndexOf( '.' );
132       if( ix != -1 )
133          fileName = fileName.substring( 0, ix );
134 
135       String type = part.getType();
136 
137       if( type.equals( Constants.WSDL11_NS ) )
138          fileName += ".wsdl";
139       else if( part.getType().equals( Constants.XSD_NS ) )
140          fileName += ".xsd";
141       else if( part.getType().equals( Constants.WADL10_NS ) )
142          fileName += ".wadl";
143       else
144          fileName += ".xml";
145 
146       if( urlPrefix != null )
147          fileName = urlPrefix + fileName;
148 
149       int cnt = 1;
150       while( urlToFileMap.containsValue( fileName ) )
151       {
152          ix = fileName.lastIndexOf( '.' );
153          fileName = fileName.substring( 0, ix ) + "_" + cnt + fileName.substring( ix );
154          cnt++;
155       }
156 
157       urlToFileMap.put( part.getUrl(), fileName );
158    }
159 
160    private void replaceImportsAndIncludes( XmlObject xmlObject, Map<String, String> urlToFileMap, String baseUrl )
161            throws Exception
162    {
163       String[] paths = getLocationXPathsToReplace();
164 
165       for( String path : paths )
166       {
167          XmlObject[] locations = xmlObject.selectPath( path );
168 
169          for( int i = 0; i < locations.length; i++ )
170          {
171             SimpleValue wsdlImport = ( ( SimpleValue ) locations[i] );
172             replaceLocation( urlToFileMap, baseUrl, wsdlImport );
173          }
174       }
175    }
176 
177    protected abstract String[] getLocationXPathsToReplace();
178 
179    private void replaceLocation( Map<String, String> urlToFileMap, String baseUrl, SimpleValue wsdlImport )
180            throws Exception
181    {
182       String location = wsdlImport.getStringValue();
183       if( location != null )
184       {
185          if( location.startsWith( "file:" ) || location.indexOf( "://" ) > 0 )
186          {
187             String newLocation = urlToFileMap.get( location );
188             if( newLocation != null )
189                wsdlImport.setStringValue( newLocation );
190             else
191                throw new Exception( "Missing local file for [" + newLocation + "]" );
192          }
193          else
194          {
195             String loc = Tools.joinRelativeUrl( baseUrl, location );
196             String newLocation = urlToFileMap.get( loc );
197             if( newLocation != null )
198                wsdlImport.setStringValue( newLocation );
199             else
200                throw new Exception( "Missing local file for [" + loc + "]" );
201          }
202       }
203    }
204 
205 }