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