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