View Javadoc

1   /*
2    *  soapUI, copyright (C) 2006 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of the GNU Lesser General Public License as published by the Free Software Foundation; 
6    *  either version 2.1 of the License, or (at your option) any later version.
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.wsdl.support.wsdl;
14  
15  import java.util.ArrayList;
16  import java.util.HashMap;
17  import java.util.Iterator;
18  import java.util.List;
19  import java.util.Map;
20  
21  import javax.wsdl.Binding;
22  import javax.wsdl.Definition;
23  import javax.wsdl.Port;
24  import javax.wsdl.PortType;
25  import javax.wsdl.Service;
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  
30  import com.eviware.soapui.SoapUI;
31  import com.eviware.soapui.impl.wsdl.WsdlInterface;
32  import com.eviware.soapui.impl.wsdl.WsdlProject;
33  import com.eviware.soapui.impl.wsdl.support.BindingImporter;
34  import com.eviware.soapui.impl.wsdl.support.soap.Soap11HttpBindingImporter;
35  import com.eviware.soapui.impl.wsdl.support.soap.Soap12HttpBindingImporter;
36  import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
37  import com.eviware.soapui.settings.WsdlSettings;
38  import com.eviware.soapui.support.UISupport;
39  
40  /***
41   * Importer for WsdlInterfaces from WSDL urls / files
42   * 
43   * @author Ole.Matzura
44   */
45  
46  public class WsdlImporter
47  {
48     private List<BindingImporter> bindingImporters = new ArrayList<BindingImporter>();
49     private static WsdlImporter instance;
50     
51     private final static Log log = LogFactory.getLog( WsdlImporter.class );
52     
53     private WsdlImporter()
54     {
55        try
56        {
57           bindingImporters.add( new Soap11HttpBindingImporter() );
58           bindingImporters.add( new Soap12HttpBindingImporter() );
59        }
60        catch (Exception e)
61        {
62           e.printStackTrace();
63        }
64     }
65  
66     public static WsdlImporter getInstance()
67     {
68        if( instance == null )
69           instance = new WsdlImporter();
70        
71        return instance;
72     }
73     
74     public WsdlInterface [] importWsdl( WsdlProject project, String wsdlUrl ) throws Exception
75     {
76        WsdlContext wsdlContext = new WsdlContext( wsdlUrl, SoapVersion.Soap11, null, null );
77        wsdlContext.load();
78        
79        List<WsdlInterface> result = new ArrayList<WsdlInterface>();
80        Map<Binding,WsdlInterface> importedBindings = new HashMap<Binding,WsdlInterface>();
81        Definition definition = wsdlContext.getDefinition();
82        
83        Map serviceMap = definition.getAllServices();
84        if( serviceMap.isEmpty() )
85           log.info(  "Missing services in [" + wsdlUrl + "], check for bindings" );
86        else
87        {
88           Iterator i = serviceMap.values().iterator();
89           while( i.hasNext() )
90           {
91              Service service = (Service) i.next();
92              Map portMap = service.getPorts();
93              Iterator i2 = portMap.values().iterator();
94              while( i2.hasNext() )
95              {
96                 Port port = (Port) i2.next();
97                 
98                 Binding binding = port.getBinding();
99                 if( importedBindings.containsKey( binding ))
100                {
101                	// add endpoint since it could differ from already imported one..
102                	String endpoint = WsdlUtils.getSoapEndpoint( port );
103 	               if( endpoint != null )
104 	                  importedBindings.get( binding ).addEndpoint( endpoint );
105 	               
106                	continue;
107                }
108                
109                String ifaceName = getInterfaceNameForBinding( binding );
110                WsdlInterface ifc = (WsdlInterface) project.getInterfaceByName( ifaceName );
111                if( ifc != null )
112                {
113                	Boolean res = UISupport.confirmOrCancel( "Interface [" + ifc.getName() + "] already exists in project, update instead?", "Import WSDL");
114                	if( res == null )
115                		return new WsdlInterface[0];
116                	
117                	if( res.booleanValue() )
118                	{
119                		ifc.updateDefinition( wsdlUrl, false );
120                		importedBindings.put( binding, ifc );
121                	}
122 
123                	continue;
124                }
125                
126                WsdlInterface iface = importBinding(project, wsdlContext, binding);
127                if( iface != null )
128                {
129                	String endpoint = WsdlUtils.getSoapEndpoint( port );
130 	               if( endpoint != null )
131 	                  iface.addEndpoint( endpoint );
132 	               
133 	               result.add( iface );
134 	               importedBindings.put( binding, iface );
135                }
136             }
137          }
138       }
139       
140       Map bindingMap = definition.getAllBindings();
141       if( !bindingMap.isEmpty())
142       {
143          Iterator i = bindingMap.values().iterator();
144          while( i.hasNext() )
145          {
146             Binding binding = (Binding) i.next();
147             if( importedBindings.containsKey( binding ))
148             {
149             	continue;
150             }
151             
152             PortType portType = binding.getPortType();
153             if( portType == null )
154             {
155             	log.warn( "Missing portType for binding [" + binding.getQName().toString() + "]" );
156             }
157             else
158             {
159             	String ifaceName = getInterfaceNameForBinding( binding );
160 					WsdlInterface ifc = (WsdlInterface) project.getInterfaceByName( ifaceName );
161 	            if( ifc != null && result.indexOf( ifc ) == -1 )
162 	            {
163 	            	Boolean res = UISupport.confirmOrCancel( "Interface [" + ifc.getName() + "] already exists in project, update instead?", "Import WSDL");
164 	            	if( res == null )
165 	            		return new WsdlInterface[0];
166 	            	
167 	            	if( res.booleanValue() )
168 	            	{
169 	            		ifc.updateDefinition( wsdlUrl, false );
170 	            		importedBindings.put( binding, ifc );
171 	            	}
172 	
173 	            	continue;
174 	            }
175 	            
176 	            WsdlInterface iface = importBinding(project, wsdlContext, binding);
177 	            if( iface != null )
178 	            {
179 	            	result.add( iface );
180 	            	importedBindings.put( binding, ifc );
181 	            }
182             }
183          }
184       }
185       
186       if( importedBindings.isEmpty() && serviceMap.isEmpty() && bindingMap.isEmpty() )
187       {
188       	UISupport.showErrorMessage( "Found nothing to import in [" + wsdlUrl + "]" );
189       }
190       
191       // only the last gets the context
192       if( result.size() > 0 )
193       	result.get( result.size()-1 ).setWsdlContext( wsdlContext );
194       
195       return result.toArray( new WsdlInterface[result.size()]);
196    }
197 
198    public final static String getInterfaceNameForBinding( Binding binding )
199 	{
200    	if( SoapUI.getSettings().getBoolean( WsdlSettings.NAME_WITH_BINDING ))
201    		return binding.getQName().getLocalPart();
202    	else
203    		return binding.getPortType().getQName().getLocalPart();
204 	}
205 
206 	private WsdlInterface importBinding(WsdlProject project, WsdlContext wsdlContext, Binding binding ) throws Exception
207    {
208       log.info( "Finding importer for " + binding.getQName() );
209       for( int c = 0; c < bindingImporters.size(); c++ )
210       {
211          BindingImporter importer = bindingImporters.get( c );
212          if( importer.canImport( binding ) )
213          {
214             log.info( "Importing binding " + binding.getQName() );
215             WsdlInterface iface = importer.importBinding( project, wsdlContext, binding );
216             iface.setDefinition( wsdlContext.getUrl(), false );
217             return iface;
218          }
219       }
220       log.info( "Missing importer for " + binding.getQName() );
221       
222       return null;
223    }
224    
225   
226   
227 }