View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 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.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  import javax.xml.namespace.QName;
27  
28  import org.apache.log4j.Logger;
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 Logger log = Logger.getLogger( 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           SoapUI.logError( e );
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     	return importWsdl( project, wsdlUrl, null );
77     }
78     
79     public WsdlInterface [] importWsdl( WsdlProject project, String wsdlUrl, QName bindingName ) throws Exception {
80        return importWsdl( project, wsdlUrl, null, null );
81    }
82     
83     public WsdlInterface [] importWsdl( WsdlProject project, String wsdlUrl, QName bindingName, WsdlLoader wsdlLoader ) throws Exception
84     {
85        WsdlContext wsdlContext = new WsdlContext( wsdlUrl, SoapVersion.Soap11, null, null );
86        if( !wsdlContext.load( wsdlLoader ))
87        {
88        	UISupport.showErrorMessage( "Failed to import WSDL" );
89        	return null;
90        }
91      
92        Definition definition = wsdlContext.getDefinition();
93        List<WsdlInterface> result = new ArrayList<WsdlInterface>();
94        if( bindingName != null )
95        {
96        	WsdlInterface iface = importBinding( project, wsdlContext, ( Binding ) definition.getAllBindings().get( bindingName ));
97        	return iface == null ? new WsdlInterface[0] : new WsdlInterface[] {iface};
98        }
99        
100       Map<Binding,WsdlInterface> importedBindings = new HashMap<Binding,WsdlInterface>();
101       
102       Map serviceMap = definition.getAllServices();
103       if( serviceMap.isEmpty() )
104          log.info(  "Missing services in [" + wsdlUrl + "], check for bindings" );
105       else
106       {
107          Iterator i = serviceMap.values().iterator();
108          while( i.hasNext() )
109          {
110             Service service = (Service) i.next();
111             Map portMap = service.getPorts();
112             Iterator i2 = portMap.values().iterator();
113             while( i2.hasNext() )
114             {
115                Port port = (Port) i2.next();
116                
117                Binding binding = port.getBinding();
118                if( importedBindings.containsKey( binding ))
119                {
120                	// add endpoint since it could differ from already imported one..
121                	String endpoint = WsdlUtils.getSoapEndpoint( port );
122 	               if( endpoint != null )
123 	                  importedBindings.get( binding ).addEndpoint( endpoint );
124 	               
125                	continue;
126                }
127                
128                String ifaceName = getInterfaceNameForBinding( binding );
129                WsdlInterface ifc = (WsdlInterface) project.getInterfaceByName( ifaceName );
130                if( ifc != null )
131                {
132                	Boolean res = UISupport.confirmOrCancel( "Interface [" + ifc.getName() + "] already exists in project, update instead?", "Import WSDL");
133                	if( res == null )
134                		return new WsdlInterface[0];
135                	
136                	if( res.booleanValue() )
137                	{
138                		if( ifc.updateDefinition( wsdlUrl, false ))
139                		{
140                			importedBindings.put( binding, ifc );
141                			result.add( ifc );
142                		}
143                	}
144 
145                	continue;
146                }
147                
148                WsdlInterface iface = importBinding(project, wsdlContext, binding);
149                if( iface != null )
150                {
151                	String endpoint = WsdlUtils.getSoapEndpoint( port );
152 	               if( endpoint != null )
153 	                  iface.addEndpoint( endpoint );
154 	               
155 	               result.add( iface );
156 	               importedBindings.put( binding, iface );
157                }
158             }
159          }
160       }
161       
162       Map bindingMap = definition.getAllBindings();
163       if( !bindingMap.isEmpty())
164       {
165          Iterator i = bindingMap.values().iterator();
166          while( i.hasNext() )
167          {
168             Binding binding = (Binding) i.next();
169             if( importedBindings.containsKey( binding ))
170             {
171             	continue;
172             }
173             
174             PortType portType = binding.getPortType();
175             if( portType == null )
176             {
177             	log.warn( "Missing portType for binding [" + binding.getQName().toString() + "]" );
178             }
179             else
180             {
181             	String ifaceName = getInterfaceNameForBinding( binding );
182 					WsdlInterface ifc = (WsdlInterface) project.getInterfaceByName( ifaceName );
183 	            if( ifc != null && result.indexOf( ifc ) == -1 )
184 	            {
185 	            	Boolean res = UISupport.confirmOrCancel( "Interface [" + ifc.getName() + "] already exists in project, update instead?", "Import WSDL");
186 	            	if( res == null )
187 	            		return new WsdlInterface[0];
188 	            	
189 	            	if( res.booleanValue() )
190 	            	{
191 	            		if( ifc.updateDefinition( wsdlUrl, false ))
192                		{
193                			importedBindings.put( binding, ifc );
194                			result.add( ifc );
195                		}
196 	            	}
197 	
198 	            	continue;
199 	            }
200 	            
201 	            WsdlInterface iface = importBinding(project, wsdlContext, binding);
202 	            if( iface != null )
203 	            {
204 	            	result.add( iface );
205 	            	importedBindings.put( binding, ifc );
206 	            }
207             }
208          }
209       }
210       
211       if( importedBindings.isEmpty() && serviceMap.isEmpty() && bindingMap.isEmpty() )
212       {
213       	UISupport.showErrorMessage( "Found nothing to import in [" + wsdlUrl + "]" );
214       }
215       
216       // only the last gets the context
217       if( result.size() > 0 )
218       	result.get( result.size()-1 ).setWsdlContext( wsdlContext );
219       
220       return result.toArray( new WsdlInterface[result.size()]);
221    }
222 
223    public final static String getInterfaceNameForBinding( Binding binding )
224 	{
225    	if( SoapUI.getSettings().getBoolean( WsdlSettings.NAME_WITH_BINDING ))
226    		return binding.getQName().getLocalPart();
227    	else
228    		return binding.getPortType().getQName().getLocalPart();
229 	}
230 
231 	private WsdlInterface importBinding(WsdlProject project, WsdlContext wsdlContext, Binding binding ) throws Exception
232    {
233       log.info( "Finding importer for " + binding.getQName() );
234       for( int c = 0; c < bindingImporters.size(); c++ )
235       {
236          BindingImporter importer = bindingImporters.get( c );
237          if( importer.canImport( binding ) )
238          {
239             log.info( "Importing binding " + binding.getQName() );
240             WsdlInterface iface = importer.importBinding( project, wsdlContext, binding );
241             iface.setDefinition( wsdlContext.getUrl(), false );
242             return iface;
243          }
244       }
245       log.info( "Missing importer for " + binding.getQName() );
246       
247       return null;
248    }
249    
250   
251   
252 }