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.actions.iface.tools.gsoap;
    14
    15  import java.io.File;
    16  import java.util.ArrayList;
    17  import java.util.List;
    18
    19  import com.eviware.soapui.SoapUI;
    20  import com.eviware.soapui.impl.wsdl.actions.iface.tools.support.AbstractToolsAction;
    21  import com.eviware.soapui.impl.wsdl.actions.iface.tools.support.ArgumentBuilder;
    22  import com.eviware.soapui.impl.wsdl.actions.iface.tools.support.ProcessToolRunner;
    23  import com.eviware.soapui.impl.wsdl.actions.iface.tools.support.ToolHost;
    24  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
    25  import com.eviware.soapui.model.iface.Interface;
    26  import com.eviware.soapui.settings.ToolsSettings;
    27  import com.eviware.soapui.support.Tools;
    28  import com.eviware.soapui.support.UISupport;
    29  import com.eviware.soapui.support.types.StringToStringMap;
    30  import com.eviware.x.form.XForm;
    31  import com.eviware.x.form.XFormDialog;
    32  import com.eviware.x.form.XFormDialogBuilder;
    33  import com.eviware.x.form.XFormFactory;
    34
    35  /***
    36   * Invokes GSoap wsdl2h
    37   *
    38   * @author Ole.Matzura
    39   */
    40
    41  /*
    42   * http://www.cs.fsu.edu/~engelen/soap.html
    43   *
    44   * Option 	Description
    45  -a 	generate indexed struct names for local elements with anonymous types
    46  -c 	generate C source code
    47  -d 	use DOM to populate xs:any and xsd:anyType elements
    48  -e 	don't qualify enum names
    49  	This option is for backward compatibility with gSOAP 2.4.1 and earlier.
    50  	The option does not produce code that conforms to WS-I Basic Profile 1.0a.
    51  -f 	generate flat C++ class hierarchy for schema extensions
    52  -g 	generate global top-level element declarations
    53  -h 	print help information
    54  -I path 	use path to find files
    55  -l 	include license information in output
    56  -m 	use xsd.h module to import primitive types
    57  -n name 	use name as the base namespace prefix name instead of ns
    58  -N name 	use name as the base namespace prefix name for service namespaces
    59  -o file 	output to file
    60  -p 	create polymorphic types with C++ inheritance hierarchy with base xsd__anyType
    61  	This is automatically performed when WSDL contains polymorphic definitions
    62  -r host:port 	connect via proxy host and port
    63  -s 	don't generate STL code (no std::string and no std::vector)
    64  -t file 	use type map file instead of the default file typemap.dat
    65  -u 	don't generate unions
    66  -v 	verbose output
    67  -w 	always wrap response parameters in a response struct
    68  -x 	don't generate _XML any/anyAttribute extensibility elements
    69  -y 	generate typedef synonyms for structs and enums
    70  -? 	print help information
    71   */
    72
    73  public class GSoapAction extends AbstractToolsAction<Interface>
    74  {
    75  //	private static final String WSDL2H_PATH = "path";
    76  	private static final String WSDL2H_OUTPUT = "file";
    77
    78  	//WSDL2H settings
    79  	private static final String GENERATE_INDEXED_STRUCT = "generate indexed struct names";
    80  	private static final String GENERATE_C_SOURCE = "generate C source code";
    81  	private static final String DOM = "use DOM";
    82  	private static final String DONT_QUALIFY_ENUM_NAMES = "don't qualify enum names";
    83  	private static final String FLAT_CPP_CLASS_HIERARCHY = "generate flat C++ class hierarchy";
    84  	private static final String GLOBAL_TOP_LEVEL_DECLARATIONS = "generate global top-level declarations";
    85  	private static final String PATH = "path to find files";
    86  	private static final String INCLUDE_LICENSE_INFORMATION = "include license information";
    87  	private static final String USE_XSD_H = "use xsd.h module";
    88  	private static final String BASE_NAMESPACE_PREFIX_INSTEAD_OF_NS = "prefixNs";
    89  	private static final String BASE_NAMESPACE_PREFIX_FOR_SERVICE_NS = "servicePrefixNs";
    90  	private static final String POLYMORPHIC_TYPES = "create polymorphic types";
    91  	private static final String PROXY_HOST_PORT = "proxy host:port";
    92  	private static final String NO_STL = "don't generate STL code";
    93  	private static final String TYPE_MAP_FILE = "use type map file";
    94  	private static final String NO_UNIONS = "don't generate unions";
    95  	private static final String VERBOSE = "verbose output";
    96  	private static final String WRAP_RESPONSE_STRUCT = "wrap response in struct";
    97  	private static final String NO_ANY = "don't generate _XML any/anyAttribute";
    98  	private static final String TYPEDEF_SYNONYMS = "generate typedef synonyms for structs and enums";
    99
    100 	//SOAPCPP2 settings
    101 	private static final String SOAP_11 = "generate SOAP 1.1 bindings";
    102 	private static final String SOAP_12 = "generate SOAP 1.2 bindings";
    103 	private static final String CLIENT_SIDE = "generate client-side code only";
    104 	private static final String SERVER_SIDE = "generate server-side code only";
    105 	private static final String NO_LIB = "don't generate soapClientLib/soapServerLib";
    106 	private static final String SOAP_ACTION = "use value of SOAPAction HTTP header to dispatch method at server side";
    107 	private static final String GENERATE_C_SOURCE_CPP = "generate C source code";
    108 //	private static final String SAVE_PATH = "use path to save files";
    109 	private static final String SOAP_RPC = "generate SOAP RPC encoding style bindings";
    110 	private static final String SERVICE_PROXIES = "generate service proxies and objects inherited from soap struct";
    111 	private static final String IMPORT_PATH = "import path(s)";
    112 	private static final String GENERATE_LINKABLE_MODULES = "generate linkable modules (experimental)";
    113 	private static final String GENERATE_MATLAB_CODE = "generate Matlab(tm) code for MEX compiler";
    114 	private static final String SERVICE_NAME = "use service name to rename service functions and namespace table";
    115 	private static final String NAME_PREFIX = "file prefix";
    116 	private static final String XSI_TYPED = "generate code for fully xsi:type typed SOAP/XML messaging";
    117 	private static final String NO_GEN_WSDL_SCHEMA = "don't generate WSDL and schema files";
    118 	private static final String NO_GEN_SAMPLE_XML = "don't generate sample XML message files";
    119
    120 	private static final String WSDL2H = "run wsdl2h";
    121 	private static final String SOAPCPP2 = "run soapcpp2";
    122 	public static final String SOAPUI_ACTION_ID = "GSoapAction";
    123
    124 	public GSoapAction()
    125    {
    126       super( "GSoap Artifacts", "Generates GSoap artifacts using wsdl2h and soap2cpp");
    127    }
    128
    129 	protected StringToStringMap initValues( Interface modelItem, Object param )
    130 	{
    131 		StringToStringMap values = super.initValues( modelItem, param );
    132
    133 		values.putIfMissing( WSDL2H, Boolean.toString( true ));
    134 		values.putIfMissing( SOAPCPP2, Boolean.toString( true ));
    135 		return values;
    136 	}
    137
    138 	protected XFormDialog buildDialog( Interface modelItem )
    139 	{
    140       XFormDialogBuilder builder = XFormFactory.createDialogBuilder("GSoap Artifacts");
    141
    142       XForm wsdl2hAdvForm = builder.createForm( "wsdl2h" );
    143
    144       wsdl2hAdvForm.addCheckBox( WSDL2H, null );
    145       addWSDLFields( wsdl2hAdvForm, modelItem );
    146
    147       wsdl2hAdvForm.addTextField( WSDL2H_OUTPUT, "name of output file", XForm.FieldType.PROJECT_FILE );
    148
    149 		XForm soapcpp2AdvForm = builder.createForm( "soapcpp2" );
    150
    151 		soapcpp2AdvForm.addCheckBox( SOAPCPP2, null );
    152
    153 		wsdl2hAdvForm.addCheckBox(GENERATE_INDEXED_STRUCT, null);
    154 		wsdl2hAdvForm.addCheckBox(GENERATE_C_SOURCE, null);
    155 		wsdl2hAdvForm.addCheckBox(DOM,null);
    156 		wsdl2hAdvForm.addCheckBox(DONT_QUALIFY_ENUM_NAMES, null);
    157 		wsdl2hAdvForm.addCheckBox(FLAT_CPP_CLASS_HIERARCHY, null);
    158 		wsdl2hAdvForm.addCheckBox(GLOBAL_TOP_LEVEL_DECLARATIONS, null);
    159 		wsdl2hAdvForm.addTextField(PATH, "use path to find files", XForm.FieldType.PROJECT_FOLDER);
    160 		wsdl2hAdvForm.addCheckBox(INCLUDE_LICENSE_INFORMATION, null);
    161 		wsdl2hAdvForm.addCheckBox(USE_XSD_H, null);
    162 		wsdl2hAdvForm.addTextField( BASE_NAMESPACE_PREFIX_INSTEAD_OF_NS, "use name as the base namespace prefix name instead of ns", XForm.FieldType.TEXT );
    163 		wsdl2hAdvForm.addTextField( BASE_NAMESPACE_PREFIX_FOR_SERVICE_NS, "use name as the base namespace prefix name for service namespaces", XForm.FieldType.TEXT );
    164
    165 		wsdl2hAdvForm.addCheckBox(POLYMORPHIC_TYPES, null);
    166 		wsdl2hAdvForm.addTextField( PROXY_HOST_PORT, "connect via proxy host and port (host:port)", XForm.FieldType.TEXT );
    167 		wsdl2hAdvForm.addCheckBox(NO_STL, null);
    168 		wsdl2hAdvForm.addTextField(TYPE_MAP_FILE, "use type map file instead of the default file typemap.dat", XForm.FieldType.PROJECT_FILE);
    169 		wsdl2hAdvForm.addCheckBox(NO_UNIONS,null);
    170 		wsdl2hAdvForm.addCheckBox(VERBOSE, null);
    171 		wsdl2hAdvForm.addCheckBox(WRAP_RESPONSE_STRUCT, null);
    172 		wsdl2hAdvForm.addCheckBox(NO_ANY, null);
    173 		wsdl2hAdvForm.addCheckBox(TYPEDEF_SYNONYMS, null);
    174
    175 		soapcpp2AdvForm.addCheckBox(SOAP_11, null);
    176 		soapcpp2AdvForm.addCheckBox(SOAP_12, null);
    177 		soapcpp2AdvForm.addCheckBox(CLIENT_SIDE, null);
    178 		soapcpp2AdvForm.addCheckBox(SERVER_SIDE, null);
    179 		soapcpp2AdvForm.addCheckBox(NO_LIB, null);
    180 		soapcpp2AdvForm.addCheckBox(SOAP_ACTION, null);
    181 		soapcpp2AdvForm.addCheckBox(GENERATE_C_SOURCE_CPP, null);
    182 		//soapcpp2AdvForm.addTextField(SAVE_PATH, "", XForm.FieldType.DIRECTORY);
    183 		soapcpp2AdvForm.addCheckBox(SOAP_RPC, null);
    184 		soapcpp2AdvForm.addCheckBox(SERVICE_PROXIES, null);
    185 		soapcpp2AdvForm.addTextField(IMPORT_PATH, "use path(s) for #import", XForm.FieldType.PROJECT_FOLDER);
    186 		soapcpp2AdvForm.addCheckBox(GENERATE_LINKABLE_MODULES, null);
    187 		soapcpp2AdvForm.addCheckBox(GENERATE_MATLAB_CODE, null);
    188 		soapcpp2AdvForm.addCheckBox(SERVICE_NAME, null);
    189 		soapcpp2AdvForm.addTextField(NAME_PREFIX, "save files with new prefix name instead of 'soap'", XForm.FieldType.TEXT);
    190 		soapcpp2AdvForm.addCheckBox(XSI_TYPED, null);
    191 		soapcpp2AdvForm.addCheckBox(NO_GEN_WSDL_SCHEMA, null);
    192 		soapcpp2AdvForm.addCheckBox(NO_GEN_SAMPLE_XML, null);
    193
    194 		return builder.buildDialog( buildDefaultActions( HelpUrls.GSOAP_HELP_URL, modelItem ),
    195       		"Specify arguments for GSoap wsdl2h and soap2cpp", UISupport.TOOL_ICON );
    196 	}
    197
    198 	protected void generate(StringToStringMap values, ToolHost toolHost, Interface modelItem ) throws Exception
    199 	{
    200 		String gsoapDir = SoapUI.getSettings().getString( ToolsSettings.GSOAP_LOCATION, null );
    201 		if( Tools.isEmpty( gsoapDir ))
    202 		{
    203 			UISupport.showErrorMessage( "GSoap directory must be set in global preferences" );
    204 			return;
    205 		}
    206
    207 		List<ProcessBuilder> builders = new ArrayList<ProcessBuilder>();
    208
    209 		if( values.getBoolean( WSDL2H ))
    210 		{
    211 			ProcessBuilder wsdl2hBuilder = new ProcessBuilder();
    212 			ArgumentBuilder wsdl2hArgs = buildWsdl2HArgs( modelItem );
    213 			wsdl2hBuilder.command( wsdl2hArgs.getArgs());
    214 			//wsdl2hBuilder.directory(new File(gsoapDir));
    215 			wsdl2hBuilder.directory ( new File(Tools.getDir( values.get( WSDL2H_OUTPUT ) )));
    216 			builders.add( wsdl2hBuilder );
    217 		}
    218
    219 		if( values.getBoolean( SOAPCPP2 ))
    220 		{
    221 			ProcessBuilder soapcpp2Builder = new ProcessBuilder();
    222 			ArgumentBuilder soapcpp2Args = buildSoapcpp2Args();
    223 			soapcpp2Builder.command( soapcpp2Args.getArgs());
    224 			soapcpp2Builder.directory( new File(Tools.getDir( values.get( WSDL2H_OUTPUT ) )));
    225
    226 			builders.add( soapcpp2Builder );
    227 		}
    228
    229 		if( builders.isEmpty() )
    230 			UISupport.showErrorMessage( "Nothing to run!" );
    231 		else
    232 			toolHost.run( new ProcessToolRunner( builders.toArray( new ProcessBuilder[builders.size()]), "GSoap", modelItem ));
    233 	}
    234
    235 	private ArgumentBuilder buildWsdl2HArgs(Interface modelItem )
    236 	{
    237 		String gsoapDir = SoapUI.getSettings().getString( ToolsSettings.GSOAP_LOCATION, null );
    238 		StringToStringMap values = dialog.getValues();
    239 		ArgumentBuilder builder = new ArgumentBuilder( values );
    240 		builder.startScript( gsoapDir + File.separator + "wsdl2h", "", "" );
    241 		builder.addArgs( new String[] { "-v" } );
    242
    243 		values.put( WSDL2H_OUTPUT, Tools.getFilename( values.get( WSDL2H_OUTPUT ) ));
    244
    245 		builder.addString( WSDL2H_OUTPUT, "-o", "");
    246 		builder.addArgs( getWsdlUrl( values, modelItem ));
    247
    248 		builder.addBoolean(GENERATE_INDEXED_STRUCT, "-a");
    249 		builder.addBoolean(GENERATE_C_SOURCE, "-c");
    250 		builder.addBoolean(DOM, "-c");
    251 		builder.addBoolean(DONT_QUALIFY_ENUM_NAMES, "-e");
    252 		builder.addBoolean(FLAT_CPP_CLASS_HIERARCHY, "-f");
    253 		builder.addBoolean(GLOBAL_TOP_LEVEL_DECLARATIONS, "-g");
    254 		builder.addString(PATH, "-I", "");
    255 		builder.addBoolean(INCLUDE_LICENSE_INFORMATION, "-l");
    256 		builder.addBoolean(USE_XSD_H, "-m");
    257 		builder.addString(BASE_NAMESPACE_PREFIX_INSTEAD_OF_NS, "-n", "");
    258 		builder.addString(BASE_NAMESPACE_PREFIX_FOR_SERVICE_NS, "-N", "");
    259 		builder.addBoolean(POLYMORPHIC_TYPES, "-p");
    260 		builder.addString(PROXY_HOST_PORT, "-r", "");
    261 		builder.addBoolean(NO_STL, "-s");
    262 		builder.addString(TYPE_MAP_FILE, "-t", "");
    263 		builder.addBoolean(NO_UNIONS, "-u");
    264 		builder.addBoolean(VERBOSE, "-v");
    265 		builder.addBoolean(WRAP_RESPONSE_STRUCT, "-w");
    266 		builder.addBoolean(NO_ANY, "-x");
    267 		builder.addBoolean(TYPEDEF_SYNONYMS, "-y");
    268 		return builder;
    269 	}
    270
    271 	private ArgumentBuilder buildSoapcpp2Args()
    272 	{
    273 		String gsoapDir = SoapUI.getSettings().getString( ToolsSettings.GSOAP_LOCATION, null );
    274 		StringToStringMap values = dialog.getValues();
    275 		ArgumentBuilder builder = new ArgumentBuilder( values );
    276 		builder.startScript( gsoapDir + File.separator + "soapcpp2", "", "" );
    277 		builder.addArgs( new String[] { "-Iimport", values.get( WSDL2H_OUTPUT ) } );
    278
    279 		builder.addBoolean(SOAP_11, "-1");
    280 		builder.addBoolean(SOAP_12, "-2");
    281 		builder.addBoolean(CLIENT_SIDE, "-C");
    282 		builder.addBoolean(SERVER_SIDE, "-S");
    283 		builder.addBoolean(NO_LIB, "-L");
    284 		builder.addBoolean(SOAP_ACTION, "-a");
    285 		builder.addBoolean(GENERATE_C_SOURCE_CPP, "-c");
    286 		builder.addBoolean(SOAP_RPC, "-e");
    287 		builder.addBoolean(SERVICE_PROXIES, "-i");
    288 		builder.addString(IMPORT_PATH, "-I", "");
    289 		builder.addBoolean(GENERATE_LINKABLE_MODULES, "-l");
    290 		builder.addBoolean(GENERATE_MATLAB_CODE, "-m");
    291 		builder.addBoolean(SERVICE_NAME, "-n");
    292 		builder.addString(NAME_PREFIX, "-p", "");
    293 		builder.addBoolean(XSI_TYPED, "-t");
    294 		builder.addBoolean(NO_GEN_WSDL_SCHEMA, "-w");
    295 		builder.addBoolean(NO_GEN_SAMPLE_XML, "-x");
    296
    297 		return builder;
    298 	}
    299 }