esdlcmd_core.cpp 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2013 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include <stdio.h>
  14. #include "jlog.hpp"
  15. #include "jfile.hpp"
  16. #include "jargv.hpp"
  17. #include "esdlcmd_common.hpp"
  18. #include "esdlcmd_core.hpp"
  19. #include "esdl2ecl.cpp"
  20. #include "esdl-publish.cpp"
  21. class Esdl2XSDCmd : public EsdlHelperConvertCmd
  22. {
  23. public:
  24. Esdl2XSDCmd() : optUnversionedNamespace(false), optInterfaceVersion(0), optAllAnnot(false), optNoAnnot(false),
  25. optEnforceOptional(true), optRawOutput(false), optXformTimes(1), optFlags(DEPFLAG_COLLAPSE|DEPFLAG_ARRAYOF),
  26. outfileext(".xsd")
  27. {}
  28. virtual bool parseCommandLineOptions(ArgvIterator &iter)
  29. {
  30. if (iter.done())
  31. {
  32. usage();
  33. return false;
  34. }
  35. //First two parameters' order is fixed.
  36. for (int par = 0; par < 2 && !iter.done(); par++)
  37. {
  38. const char *arg = iter.query();
  39. if (*arg != '-')
  40. {
  41. if (optSource.isEmpty())
  42. optSource.set(arg);
  43. else if (optService.isEmpty())
  44. optService.set(arg);
  45. else
  46. {
  47. fprintf(stderr, "\nunrecognized argument detected before required parameters: %s\n", arg);
  48. usage();
  49. return false;
  50. }
  51. }
  52. else
  53. {
  54. fprintf(stderr, "\noption detected before required parameters: %s\n", arg);
  55. usage();
  56. return false;
  57. }
  58. iter.next();
  59. }
  60. for (; !iter.done(); iter.next())
  61. {
  62. if (parseCommandLineOption(iter))
  63. continue;
  64. if (matchCommandLineOption(iter, true)!=EsdlCmdOptionMatch)
  65. return false;
  66. }
  67. return true;
  68. }
  69. virtual bool parseCommandLineOption(ArgvIterator &iter)
  70. {
  71. if (iter.matchFlag(optUnversionedNamespace, ESDLOPT_UNVERSIONED_NAMESPACE) || iter.matchFlag(optUnversionedNamespace, ESDLOPT_UNVERSIONED_NAMESPACE_S))
  72. return true;
  73. if (iter.matchOption(optInterfaceVersionStr, ESDLOPT_INTERFACE_VERSION) || iter.matchOption(optInterfaceVersionStr, ESDLOPT_INTERFACE_VERSION_S))
  74. return true;
  75. if (iter.matchOption(optService, ESDLOPT_SERVICE))
  76. return true;
  77. if (iter.matchOption(optMethod, ESDLOPT_METHOD))
  78. return true;
  79. if (iter.matchOption(optXsltPath, ESDLOPT_XSLT_PATH))
  80. return true;
  81. if (iter.matchOption(optPreprocessOutputDir, ESDLOPT_PREPROCESS_OUT))
  82. return true;
  83. if (iter.matchOption(optAnnotate, ESDLOPT_ANNOTATE))
  84. return true;
  85. if (iter.matchOption(optTargetNamespace, ESDLOPT_TARGET_NAMESPACE) || iter.matchOption(optTargetNamespace, ESDLOPT_TARGET_NS))
  86. return true;
  87. if (iter.matchOption(optOptional, ESDLOPT_OPT_PARAM_VAL) || iter.matchOption(optOptional, ESDLOPT_OPTIONAL_PARAM_VAL))
  88. return true;
  89. if (iter.matchFlag(optEnforceOptional, ESDLOPT_NO_OPTIONAL_ATTRIBUTES))
  90. return true;
  91. if (iter.matchOption(optXformTimes, ESDLOPT_NUMBER))
  92. return true;
  93. if (iter.matchFlag(optNoCollapse, ESDLOPT_NO_COLLAPSE))
  94. return true;
  95. if (iter.matchFlag(optNoArrayOf, ESDLOPT_NO_ARRAYOF))
  96. return true;
  97. StringAttr oneOption;
  98. if (iter.matchOption(oneOption, ESDLOPT_INCLUDE_PATH) || iter.matchOption(oneOption, ESDLOPT_INCLUDE_PATH_S))
  99. return false; //Return false to negate allowing the include path options from parent class
  100. if (EsdlConvertCmd::parseCommandLineOption(iter))
  101. return true;
  102. return false;
  103. }
  104. esdlCmdOptionMatchIndicator matchCommandLineOption(ArgvIterator &iter, bool finalAttempt)
  105. {
  106. return EsdlConvertCmd::matchCommandLineOption(iter, true);
  107. }
  108. virtual bool finalizeOptions(IProperties *globals)
  109. {
  110. if (optSource.isEmpty())
  111. {
  112. usage();
  113. throw( MakeStringException(0, "\nError: Source esdl parameter required\n"));
  114. }
  115. if( optService.isEmpty() )
  116. {
  117. usage();
  118. throw( MakeStringException(0, "A service name must be provided") );
  119. }
  120. if (!optInterfaceVersionStr.isEmpty())
  121. {
  122. optInterfaceVersion = atof( optInterfaceVersionStr.get() );
  123. if ( optInterfaceVersion <= 0 )
  124. {
  125. throw MakeStringException( 0, "Version option must be followed by a real number > 0" );
  126. }
  127. }
  128. if (optXsltPath.isEmpty())
  129. {
  130. StringBuffer tmp;
  131. if (getComponentFilesRelPathFromBin(tmp))
  132. optXsltPath.set(tmp.str());
  133. else
  134. optXsltPath.set(COMPONENTFILES_DIR);
  135. }
  136. fullxsltpath.set(optXsltPath);
  137. fullxsltpath.append("/xslt/esxdl2xsd.xslt");
  138. if (!optPreprocessOutputDir.isEmpty())
  139. optRawOutput = true;
  140. if (!optAnnotate.isEmpty())
  141. {
  142. if (strcmp (optAnnotate.get(), "all") ==0)
  143. {
  144. optAllAnnot = true;
  145. }
  146. else if (strcmp (optAnnotate.get(), "none") ==0)
  147. {
  148. optNoAnnot = true;
  149. }
  150. else
  151. {
  152. throw MakeStringException( 0, "--annotate option must be followed by 'all' or 'none' " );
  153. }
  154. }
  155. if (optNoCollapse)
  156. {
  157. unsetFlag(DEPFLAG_COLLAPSE);
  158. }
  159. if(optNoArrayOf)
  160. {
  161. unsetFlag(DEPFLAG_ARRAYOF);
  162. }
  163. if(optTargetNamespace.isEmpty())
  164. {
  165. optTargetNamespace.set(DEFAULT_NAMESPACE_BASE);
  166. }
  167. cmdHelper.verbose = optVerbose;
  168. return true;
  169. }
  170. virtual void doTransform(IEsdlDefObjectIterator& objs, StringBuffer &target, double version=0, IProperties *opts=NULL, const char *ns=NULL, unsigned flags=0 )
  171. {
  172. TimeSection ts("transforming via XSLT");
  173. cmdHelper.defHelper->toXSD( objs, target, EsdlXslToXsd, optInterfaceVersion, opts, NULL, optFlags );
  174. }
  175. virtual void loadTransform( StringBuffer &xsltpath, IProperties *params)
  176. {
  177. TimeSection ts("loading XSLT");
  178. cmdHelper.defHelper->loadTransform( xsltpath, params, EsdlXslToXsd );
  179. }
  180. virtual void setTransformParams(IProperties *params )
  181. {
  182. cmdHelper.defHelper->setTransformParams(EsdlXslToXsd, params);
  183. }
  184. virtual int processCMD()
  185. {
  186. cmdHelper.loadDefinition(optSource, optService.get(), optInterfaceVersion,"", optTraceFlags());
  187. createOptionals();
  188. Owned<IEsdlDefObjectIterator> structs = cmdHelper.esdlDef->getDependencies( optService.get(), optMethod.get(), ESDLOPTLIST_DELIMITER, optInterfaceVersion, opts.get(), optFlags );
  189. if( optRawOutput )
  190. {
  191. outputRaw(*structs);
  192. }
  193. if( !optXsltPath.isEmpty() )
  194. {
  195. createParams();
  196. loadTransform( fullxsltpath, params);
  197. for( unsigned i=0; i < optXformTimes; i++ )
  198. {
  199. doTransform( *structs, outputBuffer, optInterfaceVersion, opts.get(), NULL, optFlags );
  200. }
  201. outputToFile();
  202. printf( "%s\n", outputBuffer.str() );
  203. }
  204. else
  205. {
  206. throw( MakeStringException(0, "Path to /xslt/esxdl2xsd.xslt is empty, cannot perform transform.") );
  207. }
  208. return 0;
  209. }
  210. void printOptions()
  211. {
  212. puts("Options:");
  213. puts(" -iv,--interface-version <version> Constrain to interface version");
  214. puts(" --method <meth name>[;<meth name>]* Constrain to list of specific method(s)" );
  215. puts(" --xslt <xslt file path> Path to '/xslt/esxdl2xsd.xslt' file to transform EsdlDef to XSD" );
  216. puts(" --preprocess-output <rawoutput dir> Output pre-processed xml file to specified directory before applying XSLT transform" );
  217. puts(" --annotate <all | none> Flag turning on either all annotations or none. By default annotations are generated " );
  218. puts(" for Enumerations. Setting the flag to 'none' will disable even those. Setting it" );
  219. puts(" to 'all' will enable additional annotations such as collapsed, cols, form_ui, html_head and rows.");
  220. puts(" --noopt Turns off the enforcement of 'optional' attributes on elements. If no -noopt is specified then all elements with an 'optional'" );
  221. puts(" will be included in the output. By default 'optional' filtering is enforced.");
  222. puts(" -opt,--optional <param value> Value to use for optional tag filter when gathering dependencies" );
  223. puts(" An example: passing 'internal' when some Esdl definition objects have the attribute");
  224. puts(" optional(\"internal\") will ensure they appear in the XSD, otherwise they'd be filtered out");
  225. puts(" -tns,--target-namespace <target ns> The target namespace, passed to the transform via the parameter 'tnsParam'" );
  226. puts(" used for the final output of the XSD. If not supplied will default to " );
  227. puts(" http://webservices.seisint.com/<service name>" );
  228. puts(" -uvns,--unversioned-ns Do not append service interface version to namespace" );
  229. puts(" -n <int> Number of times to run transform after loading XSLT. Defaults to 1." );
  230. puts(" --show-inheritance Turns off the collapse feature. Collapsing optimizes the XML output to strip out structures" );
  231. puts(" only used for inheritance, and collapses their elements into their child. That simplifies the" );
  232. puts(" stylesheet. By default this option is on.");
  233. puts(" --no-arrayof Supresses the use of the arrrayof element. arrayof optimizes the XML output to include 'ArrayOf...'" );
  234. puts(" structure definitions for those EsdlArray elements with no item_tag attribute. Works in conjunction" );
  235. puts(" with an optimized stylesheet that doesn't generate these itself. This defaults to on.");
  236. }
  237. virtual void usage()
  238. {
  239. puts("Usage:");
  240. puts("esdl xsd sourcePath serviceName [options]\n\n" );
  241. puts("sourcePath - Absolute path to ESDL definition file" );
  242. puts(" which contains ESDL Service definition." );
  243. puts("serviceName - Name of ESDL Service defined in the given definition file.\n" );
  244. printOptions();
  245. EsdlConvertCmd::usage();
  246. }
  247. virtual void outputRaw( IEsdlDefObjectIterator& obj)
  248. {
  249. if( optRawOutput )
  250. {
  251. StringBuffer xmlOut;
  252. StringBuffer empty;
  253. xmlOut.appendf( "<esxdl name=\"%s\">", optService.get());
  254. cmdHelper.defHelper->toXML( obj, xmlOut, optInterfaceVersion, opts.get(), optFlags );
  255. xmlOut.append("</esxdl>");
  256. saveAsFile( optPreprocessOutputDir.get(), empty, xmlOut.str(), NULL );
  257. }
  258. }
  259. virtual void createOptionals()
  260. {
  261. // 09jun2011 tja: We must ensure that the opts IProperties object is
  262. // valid/non-null. This is because by passing null/invalid in to the
  263. // getDependencies call we're indicating that we want to turn off
  264. // optional filtering.
  265. if( optEnforceOptional )
  266. {
  267. opts.setown(createProperties(false));
  268. if( optOptional.length() )
  269. {
  270. opts->setProp(optOptional.get(), 1);
  271. }
  272. }
  273. }
  274. void createParams()
  275. {
  276. params.set(createProperties());
  277. generateNamespace(tns);
  278. // All params are treated as expressions, so any strings must be quoted
  279. // 1/0 are not equivalent to true/false, as 0 evaluates to true
  280. setXpathQuotedParam(params, "tnsParam", tns.str());
  281. setXpathQuotedParam(params, "optional", optOptional.str());
  282. if( optAllAnnot )
  283. {
  284. params->setProp( "all_annot_Param", "true()" );
  285. }
  286. if( optNoAnnot )
  287. {
  288. params->setProp( "no_annot_Param", "true()" );
  289. }
  290. }
  291. virtual void outputToFile()
  292. {
  293. if (!optOutDirPath.isEmpty())
  294. {
  295. StringBuffer filename;
  296. generateOutputFileName(filename);
  297. saveAsFile(optOutDirPath.get(), filename, outputBuffer.str(), NULL);
  298. }
  299. }
  300. StringBuffer & generateNamespace(StringBuffer &ns)
  301. {
  302. bool urlNamespace = false;
  303. if (startsWith(optTargetNamespace.get(), "http://"))
  304. urlNamespace = true;
  305. ns.appendf("%s%c%s", optTargetNamespace.get(), urlNamespace ? '/' : ':', optService.get());
  306. //only add methodname if single method used.
  307. if (!optMethod.isEmpty() && !strstr(optMethod.get(), ESDLOPTLIST_DELIMITER))
  308. ns.append(urlNamespace ? '/' : ':').append(optMethod.get());
  309. //todo
  310. /*
  311. StringBuffer ns_optionals;
  312. //IProperties *params = context.queryRequestParameters();
  313. Owned<IPropertyIterator> esdl_optionals = cmdHelper.esdlDef->queryOptionals()->getIterator();
  314. ForEach(*esdl_optionals)
  315. {
  316. const char *key = esdl_optionals->getPropKey();
  317. if (params->hasProp(key))
  318. {
  319. if (ns_optionals.length())
  320. ns_optionals.append(',');
  321. ns_optionals.append(key);
  322. }
  323. }
  324. if (ns_optionals.length())
  325. ns.append('(').append(ns_optionals.str()).append(')');
  326. */
  327. if (optInterfaceVersion > 0 && !optUnversionedNamespace)
  328. ns.append("@ver=").appendf("%g", optInterfaceVersion);
  329. return ns.toLowerCase();
  330. }
  331. virtual StringBuffer & generateOutputFileName( StringBuffer &filename)
  332. {
  333. filename.appendf("%s", optService.get());
  334. if (!optMethod.isEmpty() && !strstr(optMethod.get(), ESDLOPTLIST_DELIMITER))
  335. filename.append('-').append(optMethod.get());
  336. filename.append(outfileext);
  337. return filename.toLowerCase();
  338. }
  339. void saveAsFile(const char * dir, StringBuffer &outname, const char *text, const char *ext="")
  340. {
  341. StringBuffer path(dir);
  342. if( outname.length()>0 && path.charAt(path.length()) != PATHSEPCHAR && outname.charAt(0) != PATHSEPCHAR)
  343. {
  344. path.append(PATHSEPCHAR);
  345. path.append(outname);
  346. }
  347. if( ext && *ext )
  348. {
  349. path.append(ext);
  350. }
  351. Owned<IFile> file = createIFile(path.str());
  352. Owned<IFileIO> io;
  353. io.setown(file->open(IFOcreate));
  354. DBGLOG("Writing to file %s", file->queryFilename());
  355. if (io.get())
  356. io->write(0, strlen(text), text);
  357. else
  358. DBGLOG("File %s can't be created", file->queryFilename());
  359. }
  360. void setFlag( unsigned f ) { optFlags |= f; }
  361. void unsetFlag( unsigned f ) { optFlags &= ~f; }
  362. public:
  363. StringAttr optService;
  364. StringAttr optXsltPath;
  365. StringAttr optMethod;
  366. StringAttr optOptional;
  367. bool optEnforceOptional;
  368. StringAttr optAnnotate;
  369. bool optAllAnnot, optNoAnnot;
  370. StringAttr optTargetNamespace;
  371. StringAttr optPreprocessOutputDir;
  372. bool optRawOutput;
  373. StringAttr optInterfaceVersionStr;
  374. double optInterfaceVersion;
  375. unsigned int optXformTimes;
  376. unsigned optFlags;
  377. bool optNoCollapse;
  378. bool optNoArrayOf;
  379. bool optUnversionedNamespace;
  380. protected:
  381. StringBuffer outputBuffer;
  382. StringBuffer fullxsltpath;
  383. Owned<IProperties> opts;
  384. Owned<IProperties> params;
  385. StringBuffer tns;
  386. StringBuffer outfileext;
  387. };
  388. class Esdl2WSDLCmd : public Esdl2XSDCmd
  389. {
  390. public:
  391. Esdl2WSDLCmd()
  392. {
  393. outfileext.set(".wsdl");
  394. }
  395. virtual bool parseCommandLineOption(ArgvIterator &iter)
  396. {
  397. if (iter.matchFlag(optWsdlAddress, ESDLOPT_WSDL_ADDRESS))
  398. return true;
  399. if (Esdl2XSDCmd::parseCommandLineOption(iter))
  400. return true;
  401. return false;
  402. }
  403. esdlCmdOptionMatchIndicator matchCommandLineOption(ArgvIterator &iter, bool finalAttempt)
  404. {
  405. return Esdl2XSDCmd::matchCommandLineOption(iter, true);
  406. }
  407. virtual bool finalizeOptions(IProperties *globals)
  408. {
  409. if (optWsdlAddress.isEmpty())
  410. optWsdlAddress.set("localhost");
  411. return Esdl2XSDCmd::finalizeOptions(globals);
  412. }
  413. virtual void doTransform(IEsdlDefObjectIterator& objs, StringBuffer &target, double version=0, IProperties *opts=NULL, const char *ns=NULL, unsigned flags=0 )
  414. {
  415. TimeSection ts("transforming via XSLT");
  416. cmdHelper.defHelper->toWSDL(objs, target, EsdlXslToWsdl, optInterfaceVersion, opts, NULL, optFlags);
  417. }
  418. virtual void loadTransform( StringBuffer &xsltpath, IProperties *params)
  419. {
  420. TimeSection ts("loading XSLT");
  421. cmdHelper.defHelper->loadTransform( xsltpath, params, EsdlXslToWsdl );
  422. }
  423. virtual void setTransformParams(IProperties *params )
  424. {
  425. cmdHelper.defHelper->setTransformParams(EsdlXslToWsdl, params);
  426. }
  427. virtual int processCMD()
  428. {
  429. cmdHelper.loadDefinition(optSource, optService.get(), optInterfaceVersion, "", optTraceFlags());
  430. createOptionals();
  431. Owned<IEsdlDefObjectIterator> structs = cmdHelper.esdlDef->getDependencies( optService.get(), optMethod.get(), ESDLOPTLIST_DELIMITER, optInterfaceVersion, opts.get(), optFlags );
  432. if( optRawOutput )
  433. {
  434. outputRaw(*structs);
  435. }
  436. if( !optXsltPath.isEmpty() )
  437. {
  438. createParams();
  439. loadTransform( fullxsltpath, params);
  440. for( unsigned i=0; i < optXformTimes; i++ )
  441. {
  442. doTransform( *structs, outputBuffer, optInterfaceVersion, opts.get(), NULL, optFlags );
  443. }
  444. outputToFile();
  445. printf( "%s\n", outputBuffer.str() );
  446. }
  447. else
  448. {
  449. throw( MakeStringException(0, "Path to /xslt/esxdl2xsd.xslt is empty, cannot perform transform.") );
  450. }
  451. return 0;
  452. }
  453. virtual void usage()
  454. {
  455. puts("Usage:");
  456. puts("esdl wsdl sourcePath serviceName [options]\n\n" );
  457. puts("sourcePath - Absolute path to the ESDL definition file" );
  458. puts(" which contains ESDL Service definition." );
  459. puts("serviceName - Name of ESDL Service defined in the given definition file.\n" );
  460. printOptions();
  461. puts(" --wsdladdress Defines the output WSDL's location address\n");
  462. EsdlConvertCmd::usage();
  463. }
  464. virtual void createParams()
  465. {
  466. params.set(createProperties());
  467. generateNamespace(tns);
  468. // All params are treated as expressions, so any strings must be quoted
  469. // 1/0 are not equivalent to true/false, as 0 evaluates to true
  470. setXpathQuotedParam(params, "tnsParam", tns.str());
  471. setXpathQuotedParam(params, "optional", optOptional.str());
  472. if( optAllAnnot )
  473. {
  474. params->setProp( "all_annot_Param", "true()" );
  475. }
  476. if( optNoAnnot )
  477. {
  478. params->setProp( "no_annot_Param", "true()" );
  479. }
  480. params->setProp( "create_wsdl", "true()" );
  481. setXpathQuotedParam(params, "location", optWsdlAddress.str());
  482. }
  483. public:
  484. StringAttr optWsdlAddress;
  485. };
  486. #define XSLT_ESDL2JAVABASE "esdl2java_srvbase.xslt"
  487. #define XSLT_ESDL2JAVADUMMY "esdl2java_srvdummy.xslt"
  488. class Esdl2JavaCmd : public EsdlHelperConvertCmd
  489. {
  490. public:
  491. Esdl2JavaCmd() : optFlags(0)
  492. {}
  493. virtual bool parseCommandLineOptions(ArgvIterator &iter)
  494. {
  495. if (iter.done())
  496. {
  497. usage();
  498. return false;
  499. }
  500. //First two parameters' order is fixed.
  501. for (int par = 0; par < 2 && !iter.done(); par++)
  502. {
  503. const char *arg = iter.query();
  504. if (*arg != '-')
  505. {
  506. if (optSource.isEmpty())
  507. optSource.set(arg);
  508. else if (optService.isEmpty())
  509. optService.set(arg);
  510. else
  511. {
  512. fprintf(stderr, "\nunrecognized argument detected before required parameters: %s\n", arg);
  513. usage();
  514. return false;
  515. }
  516. }
  517. else
  518. {
  519. fprintf(stderr, "\noption detected before required parameters: %s\n", arg);
  520. usage();
  521. return false;
  522. }
  523. iter.next();
  524. }
  525. for (; !iter.done(); iter.next())
  526. {
  527. if (parseCommandLineOption(iter))
  528. continue;
  529. if (matchCommandLineOption(iter, true)!=EsdlCmdOptionMatch)
  530. return false;
  531. }
  532. return true;
  533. }
  534. virtual bool parseCommandLineOption(ArgvIterator &iter)
  535. {
  536. if (iter.matchOption(optService, ESDLOPT_SERVICE))
  537. return true;
  538. if (iter.matchOption(optMethod, ESDLOPT_METHOD))
  539. return true;
  540. if (iter.matchOption(optXsltPath, ESDLOPT_XSLT_PATH))
  541. return true;
  542. if (iter.matchOption(optPreprocessOutputDir, ESDLOPT_PREPROCESS_OUT))
  543. return true;
  544. if (EsdlConvertCmd::parseCommandLineOption(iter))
  545. return true;
  546. return false;
  547. }
  548. esdlCmdOptionMatchIndicator matchCommandLineOption(ArgvIterator &iter, bool finalAttempt)
  549. {
  550. return EsdlConvertCmd::matchCommandLineOption(iter, true);
  551. }
  552. virtual bool finalizeOptions(IProperties *globals)
  553. {
  554. extractEsdlCmdOption(optIncludePath, globals, ESDLOPT_INCLUDE_PATH_ENV, ESDLOPT_INCLUDE_PATH_INI, NULL, NULL);
  555. if (optSource.isEmpty())
  556. {
  557. usage();
  558. throw( MakeStringException(0, "\nError: Source file parameter required\n"));
  559. }
  560. if( optService.isEmpty() )
  561. {
  562. usage();
  563. throw( MakeStringException(0, "A service name must be provided") );
  564. }
  565. if (!optXsltPath.length())
  566. {
  567. StringBuffer binXsltPath;
  568. getComponentFilesRelPathFromBin(binXsltPath);
  569. binXsltPath.append("/xslt/");
  570. StringBuffer temp;
  571. if (checkFileExists(temp.append(binXsltPath).append(XSLT_ESDL2JAVABASE)))
  572. optXsltPath.set(binXsltPath);
  573. else
  574. optXsltPath.set(temp.set(COMPONENTFILES_DIR).append("/xslt/"));
  575. }
  576. cmdHelper.verbose = optVerbose;
  577. return true;
  578. }
  579. virtual void doTransform(IEsdlDefObjectIterator& objs, StringBuffer &out, double version=0, IProperties *opts=NULL, const char *ns=NULL, unsigned flags=0 )
  580. {
  581. }
  582. virtual void loadTransform( StringBuffer &xsltpath, IProperties *params )
  583. {
  584. }
  585. virtual void setTransformParams(IProperties *params )
  586. {
  587. }
  588. virtual int processCMD()
  589. {
  590. cmdHelper.loadDefinition(optSource, optService, 0, optIncludePath, optTraceFlags());
  591. Owned<IEsdlDefObjectIterator> structs = cmdHelper.esdlDef->getDependencies( optService, optMethod, ESDLOPTLIST_DELIMITER, 0, NULL, optFlags );
  592. if(!optPreprocessOutputDir.isEmpty())
  593. {
  594. outputRaw(*structs);
  595. }
  596. StringBuffer xsltpathServiceBase(optXsltPath);
  597. xsltpathServiceBase.append(XSLT_ESDL2JAVABASE);
  598. cmdHelper.defHelper->loadTransform( xsltpathServiceBase, NULL, EsdlXslToJavaServiceBase);
  599. cmdHelper.defHelper->toMicroService( *structs, outputBuffer, EsdlXslToJavaServiceBase, NULL, optFlags );
  600. VStringBuffer javaFileNameBase("%sServiceBase.java", optService.get());
  601. saveAsFile(".", javaFileNameBase, outputBuffer.str(), NULL);
  602. StringBuffer xsltpathServiceDummy(optXsltPath);
  603. xsltpathServiceDummy.append(XSLT_ESDL2JAVADUMMY);
  604. cmdHelper.defHelper->loadTransform( xsltpathServiceDummy, NULL, EsdlXslToJavaServiceDummy);
  605. cmdHelper.defHelper->toMicroService( *structs, outputBuffer.clear(), EsdlXslToJavaServiceDummy, NULL, optFlags );
  606. VStringBuffer javaFileNameDummy("%sServiceDummy.java", optService.get());
  607. saveAsFile(".", javaFileNameDummy, outputBuffer.str(), NULL);
  608. return 0;
  609. }
  610. void printOptions()
  611. {
  612. puts("Options:");
  613. puts(" --method <meth name>[;<meth name>]* Constrain to list of specific method(s)" );
  614. puts(" --xslt <xslt file path> Path to xslt files used to transform EsdlDef to Java code" );
  615. puts(" --preprocess-output <raw output directory> : Output pre-processed xml file to specified directory before applying XSLT transform" );
  616. puts(" --show-inheritance Turns off the collapse feature. Collapsing optimizes the XML output to strip out structures" );
  617. puts(" only used for inheritance, and collapses their elements into their child. That simplifies the" );
  618. puts(" stylesheet. By default this option is on.");
  619. puts(ESDLOPT_INCLUDE_PATH_USAGE);
  620. }
  621. virtual void usage()
  622. {
  623. puts("Usage:");
  624. puts("esdl java sourcePath serviceName [options]\n" );
  625. puts("\nsourcePath - Absolute path to the EXSDL Definition file ( XML generated from ECM )" );
  626. puts(" which contains ESDL Service definition.\n" );
  627. puts("serviceName - Name of ESDL Service defined in the given EXSDL file.\n" );
  628. printOptions();
  629. EsdlConvertCmd::usage();
  630. }
  631. virtual void outputRaw( IEsdlDefObjectIterator& obj)
  632. {
  633. if (optPreprocessOutputDir.isEmpty())
  634. return;
  635. StringBuffer xml;
  636. xml.appendf( "<esxdl name='%s'>", optService.get());
  637. cmdHelper.defHelper->toXML( obj, xml, 0, NULL, optFlags );
  638. xml.append("</esxdl>");
  639. saveAsFile(optPreprocessOutputDir, NULL, xml, NULL );
  640. }
  641. void saveAsFile(const char * dir, const char *name, const char *text, const char *ext="")
  642. {
  643. StringBuffer path(dir);
  644. if (name && *name)
  645. {
  646. if (*name!=PATHSEPCHAR)
  647. addPathSepChar(path);
  648. path.append(name);
  649. }
  650. if( ext && *ext )
  651. path.append(ext);
  652. Owned<IFile> file = createIFile(path);
  653. Owned<IFileIO> io;
  654. io.setown(file->open(IFOcreate));
  655. DBGLOG("Writing java to file %s", file->queryFilename());
  656. if (io.get())
  657. io->write(0, strlen(text), text);
  658. else
  659. DBGLOG("File %s can't be created", file->queryFilename());
  660. }
  661. void setFlag( unsigned f ) { optFlags |= f; }
  662. void unsetFlag( unsigned f ) { optFlags &= ~f; }
  663. public:
  664. StringAttr optService;
  665. StringAttr optXsltPath;
  666. StringAttr optMethod;
  667. StringAttr optPreprocessOutputDir;
  668. unsigned optFlags;
  669. protected:
  670. StringBuffer outputBuffer;
  671. Owned<IProperties> params;
  672. };
  673. #define XSLT_ESDL2CPPBASEHPP "esdl2cpp_srvbasehpp.xslt"
  674. #define XSLT_ESDL2CPPBASECPP "esdl2cpp_srvbasecpp.xslt"
  675. #define XSLT_ESDL2CPPSRVHPP "esdl2cpp_srvhpp.xslt"
  676. #define XSLT_ESDL2CPPSRVCPP "esdl2cpp_srvcpp.xslt"
  677. #define XSLT_ESDL2CPPCMAKE "esdl2cpp_cmake.xslt"
  678. #define XSLT_ESDL2CPPTYPES "esdl2cpp_types.xslt"
  679. class Esdl2CppCmd : public EsdlHelperConvertCmd
  680. {
  681. public:
  682. Esdl2CppCmd() : optFlags(0)
  683. {}
  684. virtual bool parseCommandLineOptions(ArgvIterator &iter)
  685. {
  686. if (iter.done())
  687. {
  688. usage();
  689. return false;
  690. }
  691. //First two parameters' order is fixed.
  692. for (int par = 0; par < 2 && !iter.done(); par++)
  693. {
  694. const char *arg = iter.query();
  695. if (*arg != '-')
  696. {
  697. if (optSource.isEmpty())
  698. optSource.set(arg);
  699. else if (optService.isEmpty())
  700. optService.set(arg);
  701. else
  702. {
  703. fprintf(stderr, "\nunrecognized argument detected before required parameters: %s\n", arg);
  704. usage();
  705. return false;
  706. }
  707. }
  708. else
  709. {
  710. fprintf(stderr, "\noption detected before required parameters: %s\n", arg);
  711. usage();
  712. return false;
  713. }
  714. iter.next();
  715. }
  716. for (; !iter.done(); iter.next())
  717. {
  718. if (parseCommandLineOption(iter))
  719. continue;
  720. if (matchCommandLineOption(iter, true)!=EsdlCmdOptionMatch)
  721. return false;
  722. }
  723. return true;
  724. }
  725. virtual bool parseCommandLineOption(ArgvIterator &iter)
  726. {
  727. if (iter.matchOption(optService, ESDLOPT_SERVICE))
  728. return true;
  729. if (iter.matchOption(optMethod, ESDLOPT_METHOD))
  730. return true;
  731. if (iter.matchOption(optXsltPath, ESDLOPT_XSLT_PATH))
  732. return true;
  733. if (iter.matchOption(optOutDirPath, ESDL_CONVERT_OUTDIR))
  734. return true;
  735. if (iter.matchOption(optPreprocessOutputDir, ESDLOPT_PREPROCESS_OUT))
  736. return true;
  737. if (EsdlConvertCmd::parseCommandLineOption(iter))
  738. return true;
  739. return false;
  740. }
  741. esdlCmdOptionMatchIndicator matchCommandLineOption(ArgvIterator &iter, bool finalAttempt)
  742. {
  743. return EsdlConvertCmd::matchCommandLineOption(iter, true);
  744. }
  745. virtual bool finalizeOptions(IProperties *globals)
  746. {
  747. extractEsdlCmdOption(optIncludePath, globals, ESDLOPT_INCLUDE_PATH_ENV, ESDLOPT_INCLUDE_PATH_INI, NULL, NULL);
  748. if (optSource.isEmpty())
  749. {
  750. usage();
  751. throw( MakeStringException(0, "\nError: Source file parameter required\n"));
  752. }
  753. if( optService.isEmpty() )
  754. {
  755. usage();
  756. throw( MakeStringException(0, "A service name must be provided") );
  757. }
  758. if (!optXsltPath.length())
  759. {
  760. StringBuffer binXsltPath;
  761. getComponentFilesRelPathFromBin(binXsltPath);
  762. binXsltPath.append("/xslt/");
  763. StringBuffer temp;
  764. if (checkFileExists(temp.append(binXsltPath).append(XSLT_ESDL2CPPBASEHPP)))
  765. optXsltPath.set(binXsltPath);
  766. else
  767. optXsltPath.set(temp.set(COMPONENTFILES_DIR).append("/xslt/"));
  768. }
  769. cmdHelper.verbose = optVerbose;
  770. return true;
  771. }
  772. virtual void doTransform(IEsdlDefObjectIterator& objs, StringBuffer &out, double version=0, IProperties *opts=NULL, const char *ns=NULL, unsigned flags=0 )
  773. {
  774. }
  775. virtual void loadTransform( StringBuffer &xsltpath, IProperties *params )
  776. {
  777. }
  778. virtual void setTransformParams(IProperties *params )
  779. {
  780. }
  781. virtual int processCMD()
  782. {
  783. cmdHelper.loadDefinition(optSource, optService, 0, optIncludePath, optTraceFlags());
  784. Owned<IEsdlDefObjectIterator> structs = cmdHelper.esdlDef->getDependencies( optService, optMethod, ESDLOPTLIST_DELIMITER, 0, NULL, optFlags );
  785. if(!optPreprocessOutputDir.isEmpty())
  786. {
  787. outputRaw(*structs);
  788. }
  789. StringBuffer outdir;
  790. if (optOutDirPath.length() > 0)
  791. outdir.append(optOutDirPath);
  792. else
  793. outdir.append(".");
  794. StringBuffer sourcedir(outdir);
  795. sourcedir.append(PATHSEPCHAR).append("source");
  796. StringBuffer builddir(outdir);
  797. builddir.append(PATHSEPCHAR).append("build");
  798. recursiveCreateDirectory(sourcedir.str());
  799. recursiveCreateDirectory(builddir.str());
  800. VStringBuffer hppFileNameBase("%sServiceBase.hpp", optService.get());
  801. StringBuffer xsltpath(optXsltPath);
  802. xsltpath.append(XSLT_ESDL2CPPBASEHPP);
  803. StringBuffer filefullpath;
  804. filefullpath.append(sourcedir).append(PATHSEPCHAR).append(hppFileNameBase);
  805. if (checkFileExists(filefullpath.str()))
  806. DBGLOG("ATTENTION: File %s already exists, won't generate again", filefullpath.str());
  807. else
  808. {
  809. cmdHelper.defHelper->loadTransform( xsltpath, NULL, EsdlXslToCppServiceBaseHpp);
  810. cmdHelper.defHelper->toMicroService( *structs, outputBuffer, EsdlXslToCppServiceBaseHpp, NULL, optFlags );
  811. saveAsFile(sourcedir, hppFileNameBase, outputBuffer.str(), NULL);
  812. }
  813. VStringBuffer cppFileNameBase("%sServiceBase.cpp", optService.get());
  814. outputBuffer.clear();
  815. xsltpath.clear().append(optXsltPath);
  816. xsltpath.append(XSLT_ESDL2CPPBASECPP);
  817. filefullpath.clear().append(sourcedir).append(PATHSEPCHAR).append(cppFileNameBase);
  818. if (checkFileExists(filefullpath.str()))
  819. DBGLOG("ATTENTION: File %s already exists, won't generate again", filefullpath.str());
  820. else
  821. {
  822. cmdHelper.defHelper->loadTransform( xsltpath, NULL, EsdlXslToCppServiceBaseCpp);
  823. cmdHelper.defHelper->toMicroService( *structs, outputBuffer, EsdlXslToCppServiceBaseCpp, NULL, optFlags );
  824. saveAsFile(sourcedir.str(), cppFileNameBase, outputBuffer.str(), NULL);
  825. }
  826. VStringBuffer srvHppFileNameBase("%sService.hpp", optService.get());
  827. outputBuffer.clear();
  828. xsltpath.clear().append(optXsltPath);
  829. xsltpath.append(XSLT_ESDL2CPPSRVHPP);
  830. filefullpath.clear().append(sourcedir).append(PATHSEPCHAR).append(srvHppFileNameBase);
  831. if (checkFileExists(filefullpath.str()))
  832. DBGLOG("ATTENTION: File %s already exists, won't generate again", filefullpath.str());
  833. else
  834. {
  835. cmdHelper.defHelper->loadTransform( xsltpath, NULL, EsdlXslToCppServiceHpp);
  836. cmdHelper.defHelper->toMicroService( *structs, outputBuffer, EsdlXslToCppServiceHpp, NULL, optFlags );
  837. saveAsFile(sourcedir.str(), srvHppFileNameBase, outputBuffer.str(), NULL);
  838. }
  839. VStringBuffer srvCppFileNameBase("%sService.cpp", optService.get());
  840. outputBuffer.clear();
  841. xsltpath.clear().append(optXsltPath);
  842. xsltpath.append(XSLT_ESDL2CPPSRVCPP);
  843. filefullpath.clear().append(sourcedir).append(PATHSEPCHAR).append(srvCppFileNameBase);
  844. if (checkFileExists(filefullpath.str()))
  845. DBGLOG("ATTENTION: File %s already exists, won't generate again", filefullpath.str());
  846. else
  847. {
  848. cmdHelper.defHelper->loadTransform( xsltpath, NULL, EsdlXslToCppServiceCpp);
  849. cmdHelper.defHelper->toMicroService( *structs, outputBuffer, EsdlXslToCppServiceCpp, NULL, optFlags );
  850. saveAsFile(sourcedir.str(), srvCppFileNameBase, outputBuffer.str(), NULL);
  851. }
  852. outputBuffer.clear();
  853. xsltpath.clear().append(optXsltPath);
  854. xsltpath.append(XSLT_ESDL2CPPCMAKE);
  855. filefullpath.clear().append(sourcedir).append(PATHSEPCHAR).append("CMakeLists.txt");
  856. if (checkFileExists(filefullpath.str()))
  857. DBGLOG("ATTENTION: File %s already exists, won't generate again", filefullpath.str());
  858. else
  859. {
  860. Owned<IProperties> params = createProperties();
  861. setXpathQuotedParam(params, "installdir", INSTALL_DIR);
  862. cmdHelper.defHelper->loadTransform( xsltpath, params.get(), EsdlXslToCppCMake);
  863. cmdHelper.defHelper->toMicroService( *structs, outputBuffer, EsdlXslToCppCMake, NULL, optFlags );
  864. saveAsFile(sourcedir.str(), "CMakeLists.txt", outputBuffer.str(), NULL);
  865. }
  866. outputBuffer.clear();
  867. xsltpath.clear().append(optXsltPath);
  868. xsltpath.append(XSLT_ESDL2CPPTYPES);
  869. filefullpath.clear().append(sourcedir).append(PATHSEPCHAR).append("primitivetypes.hpp");
  870. if (checkFileExists(filefullpath.str()))
  871. DBGLOG("ATTENTION: File %s already exists, won't generate again", filefullpath.str());
  872. else
  873. {
  874. cmdHelper.defHelper->loadTransform( xsltpath, NULL, EsdlXslToCppTypes);
  875. cmdHelper.defHelper->toMicroService( *structs, outputBuffer, EsdlXslToCppTypes, NULL, optFlags );
  876. saveAsFile(sourcedir.str(), "primitivetypes.hpp", outputBuffer.str(), NULL);
  877. }
  878. return 0;
  879. }
  880. void printOptions()
  881. {
  882. puts("Options:");
  883. puts(" --method <meth name>[;<meth name>]* Constrain to list of specific method(s)" );
  884. puts(" --xslt <xslt file path> Path to xslt files used to transform EsdlDef to c++ code" );
  885. puts(" --preprocess-output <raw output directory> : Output pre-processed xml file to specified directory before applying XSLT transform" );
  886. puts(" --show-inheritance Turns off the collapse feature. Collapsing optimizes the XML output to strip out structures" );
  887. puts(" only used for inheritance, and collapses their elements into their child. That simplifies the" );
  888. puts(" stylesheet. By default this option is on.");
  889. puts(ESDLOPT_INCLUDE_PATH_USAGE);
  890. }
  891. virtual void usage()
  892. {
  893. puts("Usage:");
  894. puts("esdl cpp sourcePath serviceName [options]\n" );
  895. puts("\nsourcePath - Absolute path to the EXSDL Definition file ( XML generated from ECM )" );
  896. puts(" which contains ESDL Service definition.\n" );
  897. puts("serviceName - Name of ESDL Service defined in the given EXSDL file.\n" );
  898. printOptions();
  899. EsdlConvertCmd::usage();
  900. }
  901. virtual void outputRaw( IEsdlDefObjectIterator& obj)
  902. {
  903. if (optPreprocessOutputDir.isEmpty())
  904. return;
  905. StringBuffer xml;
  906. xml.appendf( "<esxdl name='%s'>", optService.get());
  907. cmdHelper.defHelper->toXML( obj, xml, 0, NULL, optFlags );
  908. xml.append("</esxdl>");
  909. saveAsFile(optPreprocessOutputDir, NULL, xml, NULL );
  910. }
  911. void saveAsFile(const char * dir, const char *name, const char *text, const char *ext="")
  912. {
  913. StringBuffer path(dir);
  914. if (name && *name)
  915. {
  916. if (*name!=PATHSEPCHAR)
  917. addPathSepChar(path);
  918. path.append(name);
  919. }
  920. if( ext && *ext )
  921. path.append(ext);
  922. Owned<IFile> file = createIFile(path);
  923. Owned<IFileIO> io;
  924. io.setown(file->open(IFOcreate));
  925. DBGLOG("Writing c++ to file %s", file->queryFilename());
  926. if (io.get())
  927. io->write(0, strlen(text), text);
  928. else
  929. DBGLOG("File %s can't be created", file->queryFilename());
  930. }
  931. void setFlag( unsigned f ) { optFlags |= f; }
  932. void unsetFlag( unsigned f ) { optFlags &= ~f; }
  933. public:
  934. StringAttr optService;
  935. StringAttr optXsltPath;
  936. StringAttr optMethod;
  937. StringAttr optOutDirPath;
  938. StringAttr optPreprocessOutputDir;
  939. unsigned optFlags;
  940. protected:
  941. StringBuffer outputBuffer;
  942. Owned<IProperties> params;
  943. };
  944. //=========================================================================================
  945. IEsdlCommand *createCoreEsdlCommand(const char *cmdname)
  946. {
  947. if (!cmdname || !*cmdname)
  948. return NULL;
  949. if (strieq(cmdname, "XSD"))
  950. return new Esdl2XSDCmd();
  951. if (strieq(cmdname, "ECL"))
  952. return new Esdl2EclCmd();
  953. if (strieq(cmdname, "JAVA"))
  954. return new Esdl2JavaCmd();
  955. if (strieq(cmdname, "CPP"))
  956. return new Esdl2CppCmd();
  957. if (strieq(cmdname, "WSDL"))
  958. return new Esdl2WSDLCmd();
  959. if (strieq(cmdname, "PUBLISH"))
  960. return new EsdlPublishCmd();
  961. if (strieq(cmdname, "DELETE"))
  962. return new EsdlDeleteESDLDefCmd();
  963. if (strieq(cmdname, "BIND-SERVICE"))
  964. return new EsdlBindServiceCmd();
  965. if (strieq(cmdname, "BIND-METHOD"))
  966. return new EsdlBindMethodCmd();
  967. if (strieq(cmdname, "UNBIND-METHOD"))
  968. return new EsdlUnBindMethodCmd();
  969. if (strieq(cmdname, "GET-BINDING"))
  970. return new EsdlGetBindingCmd();
  971. if (strieq(cmdname, "GET-DEFINITION"))
  972. return new EsdlGetDefinitionCmd();
  973. if (strieq(cmdname, "UNBIND-SERVICE"))
  974. return new EsdlUnBindServiceCmd();
  975. if (strieq(cmdname, "LIST-DEFINITIONS"))
  976. return new EsdlListESDLDefCmd();
  977. if (strieq(cmdname, "LIST-BINDINGS"))
  978. return new EsdlListESDLBindingsCmd();
  979. if (strieq(cmdname, "BIND-LOG-TRANSFORM"))
  980. return new EsdlBindLogTransformCmd();
  981. if (strieq(cmdname, "UNBIND-LOG-TRANSFORM"))
  982. return new EsdlUnBindLogTransformCmd();
  983. if (strieq(cmdname, "MONITOR"))
  984. return createEsdlMonitorCommand(cmdname);
  985. if (strieq(cmdname, "MONITOR-TEMPLATE"))
  986. return createEsdlMonitorCommand(cmdname);
  987. return NULL;
  988. }