SchemaCommon.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2015 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 "jregexp.hpp"
  14. #include "SchemaCommon.hpp"
  15. #include "ConfigSchemaHelper.hpp"
  16. #include "SchemaMapManager.hpp"
  17. #include <cstring>
  18. using namespace CONFIGURATOR;
  19. CXSDNodeBase::CXSDNodeBase(CXSDNodeBase* pParentNode, NODE_TYPES eNodeType) : m_pParentNode(pParentNode), m_eNodeType(eNodeType)
  20. {
  21. assert(eNodeType != XSD_ERROR);
  22. switch (eNodeType)
  23. {
  24. case(XSD_ERROR):
  25. strcpy(m_pNodeType, XSD_ERROR_STR);
  26. break;
  27. case(XSD_ANNOTATION):
  28. strcpy(m_pNodeType, XSD_ANNOTATION_STR);
  29. break;
  30. case(XSD_APP_INFO):
  31. strcpy(m_pNodeType, XSD_APP_INFO_STR);
  32. break;
  33. case(XSD_ATTRIBUTE):
  34. strcpy(m_pNodeType, XSD_ATTRIBUTE_STR);
  35. break;
  36. case(XSD_ATTRIBUTE_ARRAY):
  37. strcpy(m_pNodeType, XSD_ATTRIBUTE_ARRAY_STR);
  38. break;
  39. case(XSD_ATTRIBUTE_GROUP):
  40. strcpy(m_pNodeType, XSD_ATTRIBUTE_GROUP_STR);
  41. break;
  42. case(XSD_ATTRIBUTE_GROUP_ARRAY):
  43. strcpy(m_pNodeType, XSD_ATTRIBUTE_GROUP_ARRAY_STR);
  44. break;
  45. case(XSD_CHOICE):
  46. strcpy(m_pNodeType, XSD_CHOICE_STR);
  47. break;
  48. case(XSD_COMPLEX_CONTENT):
  49. strcpy(m_pNodeType, XSD_COMPLEX_CONTENT_STR);
  50. break;
  51. case(XSD_COMPLEX_TYPE):
  52. strcpy(m_pNodeType, XSD_COMPLEX_TYPE_STR);
  53. break;
  54. case(XSD_COMPLEX_TYPE_ARRAY):
  55. strcpy(m_pNodeType, XSD_COMPLEX_TYPE_ARRAY_STR);
  56. break;
  57. case(XSD_DOCUMENTATION):
  58. strcpy(m_pNodeType, XSD_DOCUMENTATION_STR);
  59. break;
  60. case(XSD_ELEMENT):
  61. strcpy(m_pNodeType, XSD_ELEMENT_STR);
  62. break;
  63. case(XSD_ELEMENT_ARRAY):
  64. strcpy(m_pNodeType, XSD_ELEMENT_ARRAY_STR);
  65. break;
  66. case(XSD_ARRAY_OF_ELEMENT_ARRAYS):
  67. strcpy(m_pNodeType, XSD_ARRAY_ELEMENT_ARRAY_STR);
  68. break;
  69. case(XSD_EXTENSION):
  70. strcpy(m_pNodeType, XSD_EXTENSION_STR);
  71. break;
  72. case(XSD_FIELD):
  73. strcpy(m_pNodeType, XSD_FIELD_STR);
  74. break;
  75. case(XSD_FIELD_ARRAY):
  76. strcpy(m_pNodeType, XSD_FIELD_ARRAY_STR);
  77. break;
  78. case(XSD_KEY):
  79. strcpy(m_pNodeType, XSD_KEY_STR);
  80. break;
  81. case(XSD_KEY_ARRAY):
  82. strcpy(m_pNodeType, XSD_KEY_ARRAY_STR);
  83. break;
  84. case(XSD_KEYREF):
  85. strcpy(m_pNodeType, XSD_KEYREF_STR);
  86. break;
  87. case(XSD_KEYREF_ARRAY):
  88. strcpy(m_pNodeType, XSD_KEYREF_ARRAY_STR);
  89. break;
  90. case(XSD_INCLUDE):
  91. strcpy(m_pNodeType, XSD_INCLUDE_STR);
  92. break;
  93. case(XSD_INCLUDE_ARRAY):
  94. strcpy(m_pNodeType, XSD_INCLUDE_ARRAY_STR);
  95. break;
  96. case(XSD_RESTRICTION):
  97. strcpy(m_pNodeType, XSD_RESTRICTION_STR);
  98. break;
  99. case(XSD_SCHEMA):
  100. strcpy(m_pNodeType, XSD_SCHEMA_STR);
  101. break;
  102. case(XSD_SEQUENCE):
  103. strcpy(m_pNodeType, XSD_SEQUENCE_STR);
  104. break;
  105. case(XSD_SIMPLE_TYPE):
  106. strcpy(m_pNodeType, XSD_SIMPLE_TYPE_STR);
  107. break;
  108. case(XSD_SIMPLE_TYPE_ARRAY):
  109. strcpy(m_pNodeType, XSD_SIMPLE_TYPE_ARRAY_STR);
  110. break;
  111. case(XSD_ENUMERATION):
  112. strcpy(m_pNodeType, XSD_ENUMERATION_STR);
  113. break;
  114. case(XSD_ENUMERATION_ARRAY):
  115. strcpy(m_pNodeType, XSD_ENUMERATION_ARRAY_STR);
  116. break;
  117. case(XSD_LENGTH):
  118. strcpy(m_pNodeType, XSD_LENGTH_STR);
  119. break;
  120. case(XSD_FRACTION_DIGITS):
  121. strcpy(m_pNodeType, XSD_FRACTION_DIGITS_STR);
  122. break;
  123. case(XSD_MAX_EXCLUSIVE):
  124. strcpy(m_pNodeType, XSD_MAX_EXCLUSIVE_STR);
  125. break;
  126. case(XSD_MAX_INCLUSIVE):
  127. strcpy(m_pNodeType, XSD_MAX_INCLUSIVE_STR);
  128. break;
  129. case(XSD_MIN_EXCLUSIVE):
  130. strcpy(m_pNodeType, XSD_MIN_INCLUSIVE_STR);
  131. break;
  132. case(XSD_MIN_LENGTH):
  133. strcpy(m_pNodeType, XSD_MIN_LENGTH_STR);
  134. break;
  135. case(XSD_MAX_LENGTH):
  136. strcpy(m_pNodeType, XSD_MAX_LENGTH_STR);
  137. break;
  138. case(XSD_PATTERN):
  139. strcpy(m_pNodeType, XSD_PATTERN_STR);
  140. break;
  141. case(XSD_SELECTOR):
  142. strcpy(m_pNodeType, XSD_SELECTOR_STR);
  143. break;
  144. case(XSD_TOTAL_DIGITS):
  145. strcpy(m_pNodeType, XSD_TOTAL_DIGITS_STR);
  146. break;
  147. case(XSD_WHITE_SPACE):
  148. strcpy(m_pNodeType, XSD_WHITE_SPACE_STR);
  149. break;
  150. case(XSD_DT_NORMALIZED_STRING):
  151. strcpy(m_pNodeType, XSD_DATA_TYPE_NORMALIZED_STRING);
  152. break;
  153. case(XSD_DT_STRING):
  154. strcpy(m_pNodeType, XSD_DATA_TYPE_STRING);
  155. break;
  156. case(XSD_DT_TOKEN):
  157. strcpy(m_pNodeType, XSD_DATA_TYPE_TOKEN);
  158. break;
  159. case(XSD_DT_DATE):
  160. strcpy(m_pNodeType, XSD_DATA_TYPE_DATE);
  161. break;
  162. case(XSD_DT_TIME):
  163. strcpy(m_pNodeType, XSD_DATA_TYPE_TIME);
  164. break;
  165. case(XSD_DT_DATE_TIME):
  166. strcpy(m_pNodeType, XSD_DATA_TYPE_DATE_TIME);
  167. break;
  168. case(XSD_DT_DECIMAL):
  169. strcpy(m_pNodeType, XSD_DATA_TYPE_DECIMAL);
  170. break;
  171. case(XSD_DT_INT):
  172. strcpy(m_pNodeType, XSD_DATA_TYPE_INT);
  173. break;
  174. case(XSD_DT_INTEGER):
  175. strcpy(m_pNodeType, XSD_DATA_TYPE_INTEGER);
  176. break;
  177. case(XSD_DT_LONG):
  178. strcpy(m_pNodeType, XSD_DATA_TYPE_LONG);
  179. break;
  180. case(XSD_DT_NON_NEG_INTEGER):
  181. strcpy(m_pNodeType, XSD_DATA_TYPE_NON_NEGATIVE_INTEGER);
  182. break;
  183. case(XSD_DT_NON_POS_INTEGER):
  184. strcpy(m_pNodeType, XSD_DATA_TYPE_NON_POSITIVE_INTEGER);
  185. break;
  186. case(XSD_DT_NEG_INTEGER):
  187. strcpy(m_pNodeType, XSD_DATA_TYPE_NEGATIVE_INTEGER);
  188. break;
  189. case(XSD_DT_POS_INTEGER):
  190. strcpy(m_pNodeType, XSD_DATA_TYPE_POSITIVE_INTEGER);
  191. break;
  192. case(XSD_DT_BOOLEAN):
  193. strcpy(m_pNodeType, XSD_DATA_TYPE_BOOLEAN);
  194. break;
  195. default:
  196. assert(!"Unknown XSD Type"); // should never get here
  197. strcpy(m_pNodeType, XSD_ERROR_STR);
  198. break;
  199. }
  200. }
  201. CXSDNodeBase::~CXSDNodeBase()
  202. {
  203. }
  204. void CXSDNodeBase::dumpStdOut() const
  205. {
  206. dump(::std::cout);
  207. }
  208. const CXSDNodeBase* CXSDNodeBase::getConstAncestorNode(unsigned iLevel) const
  209. {
  210. CXSDNodeBase *pAncestorNode = const_cast<CXSDNodeBase*>(this);
  211. if (iLevel == 0)
  212. return this;
  213. do
  214. {
  215. pAncestorNode = const_cast<CXSDNodeBase*>(pAncestorNode->getConstParentNode());
  216. iLevel--;
  217. } while (iLevel > 0 && pAncestorNode != nullptr);
  218. return pAncestorNode;
  219. }
  220. const CXSDNodeBase* CXSDNodeBase::getParentNodeByType(NODE_TYPES eNodeType[], const CXSDNodeBase *pParent, int length) const
  221. {
  222. for (int i = 0; i < length; i++)
  223. {
  224. if (this->m_eNodeType == eNodeType[i] && pParent != nullptr)
  225. return this;
  226. }
  227. if (this->getConstParentNode() != nullptr)
  228. return this->getConstParentNode()->getParentNodeByType(eNodeType, this, length);
  229. return nullptr;
  230. }
  231. CXSDNode::CXSDNode(CXSDNodeBase *pParentNode, NODE_TYPES pNodeType) : CXSDNodeBase::CXSDNodeBase(pParentNode, pNodeType)
  232. {
  233. }
  234. bool CXSDNode::checkSelf(NODE_TYPES eNodeType, const char *pName, const char* pCompName) const
  235. {
  236. if (eNodeType & this->getNodeType() && (pName != nullptr ? !strcmp(pName, this->getNodeTypeStr()) : true))
  237. {
  238. assert(pName != nullptr); // for now pName should always be populated
  239. return true;
  240. }
  241. return false;
  242. }
  243. const CXSDNodeBase* CXSDNode::getParentNodeByType(NODE_TYPES eNodeType) const
  244. {
  245. if (this->m_eNodeType == eNodeType)
  246. return this;
  247. if (this->getConstParentNode() != nullptr)
  248. return this->getConstParentNode()->getParentNodeByType(eNodeType);
  249. return nullptr;
  250. }
  251. const CXSDNodeBase* CXSDNodeBase::getNodeByTypeAndNameAscending(NODE_TYPES eNodeType[], const char *pName, int length) const
  252. {
  253. for (int i = 0; i < length; i++)
  254. {
  255. assert(this->m_eNodeType != eNodeType[i]);
  256. if (this->getConstParentNode() != nullptr)
  257. return this->getConstParentNode()->getNodeByTypeAndNameAscending(eNodeType[i], pName);
  258. }
  259. return nullptr;
  260. }
  261. const CXSDNodeBase* CXSDNodeBase::getNodeByTypeAndNameDescending(NODE_TYPES eNodeType[], const char *pName, int length) const
  262. {
  263. assert(false); // Derived classes need to hande this
  264. UNIMPLEMENTED;
  265. return nullptr;
  266. }
  267. const CXSDNodeBase* CXSDNodeBase::getParentNodeByType(NODE_TYPES eNodeType, const CXSDNodeBase *pParent) const
  268. {
  269. if (this->getConstParentNode() == nullptr)
  270. return nullptr;
  271. else if (this->getConstParentNode()->getNodeType() == eNodeType)
  272. return this->getConstParentNode();
  273. else
  274. return this->getConstParentNode()->getParentNodeByType(eNodeType, pParent);
  275. }
  276. CXSDBuiltInDataType* CXSDBuiltInDataType::create(CXSDNodeBase* pParentNode, const char* pNodeType)
  277. {
  278. assert(pParentNode != nullptr);
  279. enum NODE_TYPES eNodeType = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getEnumFromTypeName(pNodeType);
  280. if (eNodeType != XSD_ERROR)
  281. return new CXSDBuiltInDataType(pParentNode, eNodeType);
  282. else
  283. return nullptr;
  284. }
  285. CXSDBuiltInDataType::CXSDBuiltInDataType(CXSDNodeBase* pParentNode, enum NODE_TYPES eNodeType) : CXSDNode::CXSDNode(pParentNode, eNodeType)
  286. {
  287. assert(eNodeType != XSD_ERROR);
  288. }
  289. CXSDBuiltInDataType::~CXSDBuiltInDataType()
  290. {
  291. }
  292. void CXSDBuiltInDataType::loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree)
  293. {
  294. if (this->getNodeType() == XSD_DT_STRING)
  295. {
  296. }
  297. }
  298. void CXSDBuiltInDataType::dump(::std::ostream& cout, unsigned int offset) const
  299. {
  300. offset += STANDARD_OFFSET_1;
  301. const char *pTypeNameString = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getTypeNameFromEnum(this->getNodeType(), true);
  302. quickOutHeader(cout, pTypeNameString, offset);
  303. quickOutFooter(cout, pTypeNameString, offset);
  304. }
  305. void CXSDBuiltInDataType::getDocumentation(StringBuffer &strDoc) const
  306. {
  307. UNIMPLEMENTED;
  308. }
  309. bool CXSDBuiltInDataType::checkConstraint(const char *pValue) const
  310. {
  311. if (pValue == nullptr || *pValue == 0)
  312. return true;
  313. enum NODE_TYPES eNodeType = this->getNodeType();
  314. if (eNodeType >= XSD_DT_NORMALIZED_STRING && eNodeType < XSD_ERROR)
  315. {
  316. if (XSD_DT_NORMALIZED_STRING == eNodeType)
  317. {
  318. const char key[] = "\n\r\t";
  319. if (strpbrk(pValue, key) != nullptr)
  320. return false;
  321. }
  322. else if (XSD_DT_STRING == eNodeType)
  323. {
  324. // all allowed
  325. }
  326. else if(XSD_DT_TOKEN == eNodeType)
  327. {
  328. const char key[] = "\n\r\t";
  329. if (strpbrk(pValue, key) != nullptr)
  330. return false;
  331. if (pValue[0] == ' ' || pValue[strlen(pValue)-1] == ' ' || strstr(pValue, " ")) // leading/trailing space multiple spaces
  332. return false;
  333. }
  334. else if(XSD_DT_DATE == eNodeType)
  335. {
  336. UNIMPLEMENTED;
  337. }
  338. else if(XSD_DT_TIME == eNodeType)
  339. {
  340. UNIMPLEMENTED;
  341. }
  342. else if(XSD_DT_DATE_TIME == eNodeType)
  343. {
  344. UNIMPLEMENTED;
  345. }
  346. else if(XSD_DT_DECIMAL == eNodeType)
  347. {
  348. UNIMPLEMENTED;
  349. }
  350. else if(XSD_DT_INT == eNodeType)
  351. {
  352. UNIMPLEMENTED;
  353. }
  354. else if(XSD_DT_INTEGER == eNodeType)
  355. {
  356. RegExpr expr("^(\\+|-)?\\d+$");
  357. if ((expr.find(pValue)) && (expr.findlen(0) == strlen(pValue)) == false)
  358. return false;
  359. }
  360. else if(XSD_DT_LONG == eNodeType)
  361. {
  362. UNIMPLEMENTED;
  363. }
  364. else if(XSD_DT_NON_NEG_INTEGER == eNodeType)
  365. {
  366. RegExpr expr("^\\d+$");
  367. if ((expr.find(pValue)) && (expr.findlen(0) == strlen(pValue)) == false)
  368. return false;
  369. }
  370. else if(XSD_DT_NON_POS_INTEGER == eNodeType)
  371. {
  372. RegExpr expr("^\\d-$");
  373. if ((expr.find(pValue)) && (expr.findlen(0) == strlen(pValue)) == false)
  374. return false;
  375. }
  376. else if(XSD_DT_NEG_INTEGER == eNodeType)
  377. {
  378. UNIMPLEMENTED;
  379. }
  380. else if(XSD_DT_POS_INTEGER == eNodeType)
  381. {
  382. UNIMPLEMENTED;
  383. }
  384. else if(XSD_DT_BOOLEAN == eNodeType)
  385. {
  386. if (stricmp(pValue,"true") != 0 && stricmp(pValue,"false") != 0)
  387. return false;
  388. else
  389. assert("!Unknown datatype");
  390. }
  391. }
  392. return true;
  393. }