View Javadoc

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