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 }