params2xml.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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. #pragma warning(disable : 4786)
  14. #include "jliball.hpp"
  15. #include "esdl_def.hpp"
  16. #include "params2xml.hpp"
  17. void child2xml(IEsdlDefinition *esdl, IEsdlDefObject &child, StringBuffer &flexpath, IProperties *params, StringBuffer &xmlstr, StringBuffer &path, unsigned flags, double ver, int flexpath_setpoint);
  18. void paramsBaseStruct2xml(IEsdlDefinition *esdl, IEsdlDefStruct *est, IProperties *params, StringBuffer &xmlstr, StringBuffer &path, StringBuffer &flexpath, unsigned flexpath_setpoint, unsigned flags, double ver)
  19. {
  20. if (esdl && est && est->queryProp("base_type"))
  21. {
  22. IEsdlDefStruct *base = esdl->queryStruct(est->queryProp("base_type"));
  23. if (base)
  24. {
  25. if (base->queryProp("base_type"))
  26. paramsBaseStruct2xml(esdl, base, params, xmlstr, path, flexpath, flexpath_setpoint, flags, ver);
  27. Owned<IEsdlDefObjectIterator> bt = base->getChildren();
  28. ForEach(*bt)
  29. child2xml(esdl, bt->query(), flexpath, params, xmlstr, path, flags, ver, flexpath_setpoint);
  30. }
  31. }
  32. }
  33. void paramsStruct2xml(IEsdlDefinition *esdl, IEsdlDefStruct *est, const char *tagname, IProperties *params, StringBuffer &xmlstr, StringBuffer &path, unsigned flags, double ver, bool isroot)
  34. {
  35. xmlstr.append('<').append(tagname).append('>');
  36. unsigned xml_setpoint=xmlstr.length();
  37. StringBuffer flexpath(path);
  38. if (flexpath.length())
  39. flexpath.append(".");
  40. unsigned flexpath_setpoint = flexpath.length();
  41. paramsBaseStruct2xml(esdl, est, params, xmlstr, path, flexpath, flexpath_setpoint, flags, ver);
  42. Owned<IEsdlDefObjectIterator> it = est->getChildren();
  43. ForEach(*it)
  44. child2xml(esdl, it->query(), flexpath, params, xmlstr, path, flags, ver, flexpath_setpoint);
  45. if (isroot || xml_setpoint<xmlstr.length())
  46. xmlstr.append("</").append(tagname).append('>');
  47. else
  48. xmlstr.setLength(xml_setpoint - strlen(tagname) - 2);
  49. }
  50. esdl_decl void params2xml(IEsdlDefinition *def, const char *structname, IProperties *params, StringBuffer &xmlstr, unsigned flags, double ver)
  51. {
  52. IEsdlDefStruct *est = def->queryStruct(structname);
  53. if (!est)
  54. throw MakeStringException(-1, "parms2xml: ESDL Struct %s not found", structname);
  55. StringBuffer path;
  56. paramsStruct2xml(def, est, structname, params, xmlstr, path, flags, ver, true);
  57. }
  58. esdl_decl void params2xml(IEsdlDefinition *def, const char *service, const char *method, EsdlDefTypeId esdltype, IProperties *params, StringBuffer &xmlstr, unsigned flags, double ver)
  59. {
  60. if (esdltype!=EsdlTypeRequest && esdltype!=EsdlTypeResponse)
  61. throw MakeStringException(-1, "parms2xml: Only ESDL request and response types supported");
  62. IEsdlDefService *srv = def->queryService(service);
  63. if (!srv)
  64. throw MakeStringException(-1, "parms2xml: ESDL Service %s not found", service);
  65. IEsdlDefMethod *mth = srv->queryMethodByName(method);
  66. if (!mth)
  67. throw MakeStringException(-1, "parms2xml: ESDL Method %s not found", method);
  68. if (esdltype==EsdlTypeRequest)
  69. params2xml(def, mth->queryRequestType(), params, xmlstr, flags, ver);
  70. else if (esdltype==EsdlTypeResponse)
  71. params2xml(def, mth->queryResponseType(), params, xmlstr, flags, ver);
  72. }
  73. void child2xml(IEsdlDefinition *esdl, IEsdlDefObject &child, StringBuffer &flexpath, IProperties *params, StringBuffer &xmlstr, StringBuffer &path, unsigned flags, double ver, int flexpath_setpoint)
  74. {
  75. if (child.checkVersion(ver))
  76. {
  77. const char *name = child.queryName();
  78. const char *xml_tag = child.queryProp("xml_tag");
  79. const char *tagname;
  80. if (xml_tag && *xml_tag && flags & PARAMS2XML_OUTPUT_XML_TAG_NAME)
  81. tagname = xml_tag;
  82. else
  83. tagname = name;
  84. if (xml_tag && *xml_tag && flags & PARAMS2XML_INPUT_XML_TAG_NAME)
  85. name = xml_tag;
  86. switch (child.getEsdlType())
  87. {
  88. case EsdlTypeElement:
  89. {
  90. flexpath.append(name);
  91. const char *complex_type = child.queryProp("complex_type");
  92. if (complex_type)
  93. {
  94. IEsdlDefStruct *cst = esdl->queryStruct(complex_type);
  95. if (cst)
  96. paramsStruct2xml(esdl, cst, tagname, params, xmlstr, flexpath, flags, ver, false);
  97. }
  98. else
  99. {
  100. const char *val = params->queryProp(flexpath.str());
  101. if (val && *val)
  102. {
  103. xmlstr.append('<').append(tagname).append('>');
  104. encodeUtf8XML(val, xmlstr);
  105. xmlstr.append("</").append(tagname).append('>');
  106. }
  107. }
  108. flexpath.setLength(flexpath_setpoint);
  109. break;
  110. }
  111. case EsdlTypeEnumRef:
  112. {
  113. flexpath.append(name);
  114. const char *val = params->queryProp(flexpath.str());
  115. if (val && *val)
  116. {
  117. xmlstr.append('<').append(tagname).append('>');
  118. encodeUtf8XML(val, xmlstr);
  119. xmlstr.append("</").append(tagname).append('>');
  120. }
  121. flexpath.setLength(flexpath_setpoint);
  122. break;
  123. }
  124. case EsdlTypeArray:
  125. {
  126. const char *item_tag = child.queryProp("item_tag");
  127. if (!item_tag || !*item_tag)
  128. item_tag = "item";
  129. const char *artype = child.queryProp("type");
  130. IEsdlDefStruct *cst = esdl->queryStruct(artype);
  131. IEsdlDefArray* defArray = dynamic_cast<IEsdlDefArray*>(&child);
  132. bool isEsdlList = defArray->checkIsEsdlList();
  133. flexpath.append(name);
  134. if (cst)
  135. {
  136. flexpath.append('.').append(artype);
  137. unsigned arpath_setpoint = flexpath.length();
  138. flexpath.append('.').append("itemcount");
  139. const char *countstr = params->queryProp(flexpath.str());
  140. flexpath.setLength(arpath_setpoint);
  141. int itemcount = (countstr) ? atoi(countstr) : 0;
  142. if (itemcount)
  143. {
  144. if (isEsdlList)
  145. item_tag = name;
  146. else
  147. xmlstr.append('<').append(name).append('>');
  148. unsigned arxml_setpoint = xmlstr.length();
  149. for (int pos = 0; pos < itemcount; pos++)
  150. {
  151. flexpath.append('.').append(pos);
  152. paramsStruct2xml(esdl, cst, item_tag, params, xmlstr, flexpath, flags, ver, false);
  153. flexpath.setLength(arpath_setpoint);
  154. }
  155. if (!isEsdlList)
  156. {
  157. if (xmlstr.length()>arxml_setpoint)
  158. xmlstr.append("</").append(name).append('>');
  159. else
  160. xmlstr.setLength(arxml_setpoint - strlen(name) - 2);
  161. }
  162. }
  163. }
  164. else
  165. {
  166. const char *val = params->queryProp(flexpath.str());
  167. if (val && *val)
  168. {
  169. if (isEsdlList)
  170. item_tag = name;
  171. else
  172. xmlstr.append('<').append(name).append('>');
  173. unsigned arxml_setpoint = xmlstr.length();
  174. StringBuffer itemval;
  175. for (const char *finger=val; *finger; finger++)
  176. {
  177. if (strchr("\n\r", *finger))
  178. {
  179. if (itemval.length())
  180. {
  181. xmlstr.append('<').append(item_tag).append('>');
  182. encodeUtf8XML(itemval.str(), xmlstr);
  183. xmlstr.append("</").append(item_tag).append('>');
  184. }
  185. itemval.clear();
  186. }
  187. else
  188. itemval.append(*finger);
  189. }
  190. if (!itemval.isEmpty()) //Last item has not been added yet!
  191. {
  192. xmlstr.append('<').append(item_tag).append('>');
  193. encodeUtf8XML(itemval.str(), xmlstr);
  194. xmlstr.append("</").append(item_tag).append('>');
  195. }
  196. if (!isEsdlList)
  197. {
  198. if (xmlstr.length()>arxml_setpoint)
  199. xmlstr.append("</").append(name).append('>');
  200. else
  201. xmlstr.setLength(arxml_setpoint - strlen(name) - 2);
  202. }
  203. }
  204. }
  205. flexpath.setLength(flexpath_setpoint);
  206. break;
  207. }
  208. default:
  209. break;
  210. };
  211. }
  212. }