ConfigSchemaHelper.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2016 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 "jptree.hpp"
  14. #include "XMLTags.h"
  15. #include <cstring>
  16. #include "jfile.hpp"
  17. #include "ConfigSchemaHelper.hpp"
  18. #include "SchemaAttributes.hpp"
  19. #include "SchemaElement.hpp"
  20. #include "SchemaEnumeration.hpp"
  21. #include "ExceptionStrings.hpp"
  22. #include "BuildSet.hpp"
  23. #include "SchemaMapManager.hpp"
  24. #include "ConfigSchemaHelper.hpp"
  25. #include "ConfigFileUtils.hpp"
  26. #include "JSONMarkUp.hpp"
  27. #define SUCCESS 0
  28. #define FAILURE 1
  29. #define LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET \
  30. int nComponentCount = CBuildSetManager::getInstance()->getBuildSetComponentCount(); \
  31. \
  32. for (int idx = 0; idx < nComponentCount; idx++)
  33. using namespace CONFIGURATOR;
  34. CConfigSchemaHelper* CConfigSchemaHelper::s_pCConfigSchemaHelper = nullptr;
  35. CConfigSchemaHelper* CConfigSchemaHelper::getInstance(const char* pDefaultDirOverride)
  36. {
  37. // not thread safe!!!
  38. if (s_pCConfigSchemaHelper == nullptr)
  39. {
  40. s_pCConfigSchemaHelper = new CConfigSchemaHelper();
  41. s_pCConfigSchemaHelper->m_nTables = 0;
  42. if (pDefaultDirOverride != nullptr && pDefaultDirOverride[0] != 0)
  43. s_pCConfigSchemaHelper->setBasePath(pDefaultDirOverride);
  44. }
  45. return s_pCConfigSchemaHelper;
  46. }
  47. CConfigSchemaHelper* CConfigSchemaHelper::getInstance(const char* pBuildSetFileName, const char *pBaseDirectory, const char *pDefaultDirOverride)
  48. {
  49. assert(pBuildSetFileName != nullptr);
  50. assert(pBaseDirectory != nullptr);
  51. if (s_pCConfigSchemaHelper == nullptr && pBuildSetFileName != nullptr && pBaseDirectory != nullptr)
  52. {
  53. s_pCConfigSchemaHelper = new CConfigSchemaHelper(pBuildSetFileName, pBaseDirectory, pDefaultDirOverride);
  54. s_pCConfigSchemaHelper->m_nTables = 0;
  55. }
  56. return s_pCConfigSchemaHelper;
  57. }
  58. CConfigSchemaHelper::CConfigSchemaHelper(const char* pBuildSetFile, const char* pBuildSetDir, const char* pDefaultDirOverride) : m_pBasePath(nullptr), m_nTables(0),\
  59. m_pEnvPropertyTree(nullptr), m_pSchemaMapManager(nullptr)
  60. {
  61. assert(pBuildSetFile != nullptr);
  62. assert(pBuildSetDir != nullptr);
  63. CBuildSetManager::getInstance(pBuildSetFile, pBuildSetDir);
  64. m_pSchemaMapManager = new CSchemaMapManager();
  65. }
  66. CConfigSchemaHelper::~CConfigSchemaHelper()
  67. {
  68. delete[] m_pBasePath;
  69. delete CConfigSchemaHelper::m_pSchemaMapManager;
  70. CConfigSchemaHelper::m_pSchemaMapManager = nullptr;
  71. CConfigSchemaHelper::s_pCConfigSchemaHelper = nullptr;
  72. }
  73. bool CConfigSchemaHelper::populateSchema()
  74. {
  75. assert(m_pSchemaMapManager != nullptr);
  76. LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
  77. {
  78. const char *pSchemaName = CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx);
  79. if (pSchemaName != nullptr)
  80. {
  81. CXSDNodeBase *pNodeBase = nullptr;
  82. CSchema *pSchema = CSchema::load(pSchemaName, pNodeBase);
  83. assert(pSchema->getLinkCount() == 1);
  84. m_pSchemaMapManager->setSchemaForXSD(pSchemaName, pSchema);
  85. }
  86. }
  87. populateEnvXPath();
  88. return true;
  89. }
  90. void CConfigSchemaHelper::printConfigSchema(StringBuffer &strXML) const
  91. {
  92. assert(m_pSchemaMapManager != nullptr);
  93. const char *pComponent = nullptr;
  94. CSchema* pSchema = nullptr;
  95. LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
  96. {
  97. const char *pSchemaName = CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx);
  98. if (pComponent == nullptr || strcmp(pComponent, pSchemaName) == 0)
  99. {
  100. if (pSchemaName == nullptr)
  101. continue;
  102. pSchema = m_pSchemaMapManager->getSchemaForXSD(pSchemaName);
  103. if (pSchema != nullptr)
  104. {
  105. if (strXML.length() > 0 ? strcmp(strXML.str(), pSchemaName) == 0 : true)
  106. pSchema->dump(::std::cout);
  107. }
  108. }
  109. }
  110. }
  111. void CConfigSchemaHelper::printDocumentation(const char* comp, char **pOutput) const
  112. {
  113. assert(comp != nullptr && *comp != 0);
  114. assert(m_pSchemaMapManager != nullptr);
  115. if (!comp || !*comp)
  116. return;
  117. CSchema* pSchema = nullptr;
  118. LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
  119. {
  120. const char *pSchemaName = CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx);
  121. if (pSchemaName != nullptr && strcmp(comp, pSchemaName) == 0)
  122. {
  123. pSchema = m_pSchemaMapManager->getSchemaForXSD(pSchemaName);
  124. assert(pSchema != nullptr);
  125. if (pSchema != nullptr)
  126. {
  127. StringBuffer strDoc;
  128. pSchema->getDocumentation(strDoc);
  129. *pOutput = new char[strDoc.length()+1];
  130. sprintf(*pOutput,"%s",strDoc.str());
  131. return;
  132. }
  133. }
  134. }
  135. *pOutput = nullptr;
  136. }
  137. void CConfigSchemaHelper::printJSON(const char* comp, char **pOutput, int nIdx, bool bCleanUp) const
  138. {
  139. if (! (comp != nullptr && *comp != 0) )
  140. {
  141. DBGLOG("no component selected for JSON, index = %d", nIdx);
  142. return;
  143. }
  144. assert(m_pSchemaMapManager != nullptr);
  145. StringBuffer strJSON;
  146. strJSON.clear();
  147. resetTables();
  148. CSchema* pSchema = nullptr;
  149. LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
  150. {
  151. const char *pSchemaName = CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx);
  152. if (pSchemaName != nullptr && strcmp(comp, pSchemaName) == 0)
  153. {
  154. pSchema = m_pSchemaMapManager->getSchemaForXSD(pSchemaName);
  155. assert(pSchema != nullptr);
  156. if (pSchema != nullptr)
  157. {
  158. pSchema->getJSON(strJSON, 0, nIdx);
  159. *pOutput = new char[strJSON.length()+1];
  160. if (bCleanUp == true)
  161. {
  162. this->clearLF(strJSON);
  163. strJSON.replaceString("\\","\\\\");
  164. }
  165. sprintf(*pOutput,"%s",strJSON.str());
  166. return;
  167. }
  168. else
  169. *pOutput = nullptr;
  170. }
  171. }
  172. }
  173. void CConfigSchemaHelper::printJSONByKey(const char* key, char **pOutput, bool bCleanUp) const
  174. {
  175. if ( !key || !*key)
  176. {
  177. DBGLOG("no component key provided for to generate JSON");
  178. return;
  179. }
  180. assert(m_pSchemaMapManager != nullptr);
  181. if (key[0] == '#')
  182. key = &(key[1]);
  183. StringBuffer strKey(key);
  184. StringBuffer strJSON;
  185. resetTables();
  186. const char *pChar = strrchr(key,'[');
  187. assert(pChar != nullptr);
  188. int length = strlen(pChar);
  189. assert(length >= 3);
  190. StringBuffer strIdx;
  191. pChar++;
  192. do
  193. {
  194. strIdx.append(*pChar);
  195. pChar++;
  196. } while (*pChar != 0 && *pChar != ']');
  197. int nIndexForJSON = atoi(strIdx.str());
  198. strKey.setLength(strKey.length()-length); // remove [N] from XPath;
  199. CSchema* pSchema = nullptr;
  200. LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
  201. {
  202. const char *pProcessName = CBuildSetManager::getInstance()->getBuildSetProcessName(idx);
  203. if (pProcessName != nullptr && strcmp(strKey.str(), pProcessName) == 0)
  204. {
  205. pSchema = m_pSchemaMapManager->getSchemaForXSD(CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx));
  206. assert(pSchema != nullptr);
  207. if (pSchema != nullptr)
  208. {
  209. pSchema->getJSON(strJSON, 0, nIndexForJSON-1);
  210. *pOutput = (char*)malloc((sizeof(char))* (strJSON.length())+1);
  211. if (bCleanUp == true)
  212. {
  213. this->clearLF(strJSON);
  214. strJSON.replaceString("\\","\\\\");
  215. }
  216. sprintf(*pOutput,"%s",strJSON.str());
  217. return;
  218. }
  219. else
  220. *pOutput = nullptr;
  221. }
  222. }
  223. }
  224. void CConfigSchemaHelper::printNavigatorJSON(char **pOutput, bool bCleanUp) const
  225. {
  226. StringBuffer strJSON;
  227. CJSONMarkUpHelper::getNavigatorJSON(strJSON);
  228. if (strJSON.length() == 0)
  229. *pOutput = nullptr;
  230. *pOutput = (char*)malloc((sizeof(char))* (strJSON.length())+1);
  231. if (bCleanUp == true)
  232. {
  233. this->clearLF(strJSON);
  234. strJSON.replaceString("\\","\\\\");
  235. }
  236. sprintf(*pOutput,"%s",strJSON.str());
  237. return;
  238. }
  239. void CConfigSchemaHelper::printDump(const char* comp) const
  240. {
  241. assert(comp != nullptr && *comp != 0);
  242. assert(m_pSchemaMapManager != nullptr);
  243. if (comp == nullptr || *comp == 0)
  244. return;
  245. CSchema* pSchema = nullptr;
  246. LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
  247. {
  248. const char *pSchemaName = CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx);
  249. if (pSchemaName != nullptr && strcmp(comp, pSchemaName) == 0)
  250. {
  251. pSchema = m_pSchemaMapManager->getSchemaForXSD(pSchemaName);
  252. assert(pSchema != nullptr);
  253. if (pSchema != nullptr)
  254. pSchema->dump(::std::cout);
  255. }
  256. }
  257. }
  258. //test purposes
  259. bool CConfigSchemaHelper::getXMLFromSchema(StringBuffer& strXML, const char* pComponent)
  260. {
  261. assert (m_pSchemaMapManager != nullptr);
  262. CSchema* pSchema = nullptr;
  263. strXML.append(CONFIGURATOR_HEADER);
  264. LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
  265. {
  266. const char *pSchemaName = CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx);
  267. if (pComponent == nullptr || strcmp(pComponent, pSchemaName) == 0)
  268. {
  269. if (pSchemaName == nullptr)
  270. continue;
  271. pSchema = m_pSchemaMapManager->getSchemaForXSD(pSchemaName);
  272. if (pSchema != nullptr)
  273. strXML.append(pSchema->getXML(nullptr));
  274. }
  275. }
  276. strXML.append("\t</Software>\n</Environment>\n");
  277. return true;
  278. }
  279. void CConfigSchemaHelper::addExtensionToBeProcessed(CExtension *pExtension)
  280. {
  281. assert(pExtension != nullptr);
  282. if (pExtension != nullptr)
  283. m_extensionArr.append(*pExtension);
  284. }
  285. void CConfigSchemaHelper::addAttributeGroupToBeProcessed(CAttributeGroup *pAttributeGroup)
  286. {
  287. assert(pAttributeGroup != nullptr);
  288. if (pAttributeGroup != nullptr)
  289. m_attributeGroupArr.append(*pAttributeGroup);
  290. }
  291. void CConfigSchemaHelper::addNodeForTypeProcessing(CXSDNodeWithType *pNode)
  292. {
  293. assert(pNode != nullptr);
  294. if (pNode != nullptr)
  295. m_nodeWithTypeArr.append(*pNode);
  296. }
  297. void CConfigSchemaHelper::addNodeForBaseProcessing(CXSDNodeWithBase *pNode)
  298. {
  299. assert(pNode != nullptr);
  300. if (pNode != nullptr)
  301. m_nodeWithBaseArr.append(*pNode);
  302. }
  303. void CConfigSchemaHelper::processExtensionArr()
  304. {
  305. int length = m_extensionArr.length();
  306. for (int idx = 0; idx < length; idx++)
  307. {
  308. CExtension &extension = (m_extensionArr.item(idx));
  309. const char *pName = extension.getBase();
  310. assert(pName != nullptr);
  311. if (pName != nullptr)
  312. {
  313. CXSDNode *pNodeBase = nullptr;
  314. pNodeBase = m_pSchemaMapManager->getSimpleTypeWithName(pName) != nullptr ? dynamic_cast<CSimpleType*>(m_pSchemaMapManager->getSimpleTypeWithName(pName)) : nullptr;
  315. if (pNodeBase == nullptr)
  316. pNodeBase = m_pSchemaMapManager->getComplexTypeWithName(pName) != nullptr ? dynamic_cast<CComplexType*>(m_pSchemaMapManager->getComplexTypeWithName(pName)) : nullptr ;
  317. assert(pNodeBase != nullptr);
  318. if (pNodeBase != nullptr)
  319. extension.setBaseNode(pNodeBase);
  320. }
  321. }
  322. m_extensionArr.popAll(false);
  323. }
  324. void CConfigSchemaHelper::processAttributeGroupArr()
  325. {
  326. aindex_t length = m_attributeGroupArr.length();
  327. for (aindex_t idx = 0; idx < length; idx++)
  328. {
  329. CAttributeGroup &attributeGroup = (m_attributeGroupArr.item(idx));
  330. const char *pRef = attributeGroup.getRef();
  331. assert(pRef != nullptr && pRef[0] != 0);
  332. if (pRef != nullptr && pRef[0] != 0)
  333. {
  334. assert(m_pSchemaMapManager != nullptr);
  335. CAttributeGroup *pAttributeGroup = m_pSchemaMapManager->getAttributeGroupFromXPath(pRef);
  336. assert(pAttributeGroup != nullptr);
  337. if (pAttributeGroup != nullptr)
  338. attributeGroup.setRefNode(pAttributeGroup);
  339. }
  340. }
  341. m_attributeGroupArr.popAll(true);
  342. }
  343. void CConfigSchemaHelper::processNodeWithTypeArr(CXSDNodeBase *pParentNode)
  344. {
  345. int length = m_nodeWithTypeArr.length();
  346. for (int idx = 0; idx < length; idx++)
  347. {
  348. CXSDNodeWithType *pNodeWithType = &(m_nodeWithTypeArr.item(idx));
  349. const char *pTypeName = pNodeWithType->getType();
  350. assert(pTypeName != nullptr);
  351. if (pTypeName != nullptr)
  352. {
  353. CXSDNode *pNode = nullptr;
  354. pNode = m_pSchemaMapManager->getSimpleTypeWithName(pTypeName) != nullptr ? dynamic_cast<CSimpleType*>(m_pSchemaMapManager->getSimpleTypeWithName(pTypeName)) : nullptr;
  355. if (pNode == nullptr)
  356. pNode = m_pSchemaMapManager->getComplexTypeWithName(pTypeName) != nullptr ? dynamic_cast<CComplexType*>(m_pSchemaMapManager->getComplexTypeWithName(pTypeName)) : nullptr;
  357. if (pNode == nullptr)
  358. pNode = CXSDBuiltInDataType::create(pNodeWithType, pTypeName);
  359. if (pNode != nullptr)
  360. pNodeWithType->setTypeNode(pNode);
  361. else
  362. PROGLOG("Unsupported type '%s'", pTypeName);
  363. }
  364. }
  365. m_nodeWithTypeArr.popAll(true);
  366. }
  367. void CConfigSchemaHelper::processNodeWithBaseArr()
  368. {
  369. int length = m_nodeWithBaseArr.length();
  370. for (int idx = 0; idx < length; idx++)
  371. {
  372. CXSDNodeWithBase *pNodeWithBase = &(this->m_nodeWithBaseArr.item(idx));
  373. const char *pBaseName = pNodeWithBase->getBase();
  374. assert(pBaseName != nullptr);
  375. if (pBaseName != nullptr)
  376. {
  377. CXSDNode *pNode = nullptr;
  378. pNode = m_pSchemaMapManager->getSimpleTypeWithName(pBaseName) != nullptr ? dynamic_cast<CSimpleType*>(m_pSchemaMapManager->getSimpleTypeWithName(pBaseName)) : nullptr;
  379. if (pNode == nullptr)
  380. pNode = m_pSchemaMapManager->getComplexTypeWithName(pBaseName) != nullptr ? dynamic_cast<CComplexType*>(m_pSchemaMapManager->getComplexTypeWithName(pBaseName)) : nullptr;
  381. if (pNode == nullptr)
  382. pNode = CXSDBuiltInDataType::create(pNode, pBaseName);
  383. assert(pNode != nullptr);
  384. if (pNode != nullptr)
  385. pNodeWithBase->setBaseNode(pNode);
  386. else
  387. PROGLOG("Unsupported type '%s'", pBaseName);
  388. }
  389. }
  390. m_nodeWithBaseArr.popAll(false);
  391. }
  392. void CConfigSchemaHelper::addElementForRefProcessing(CElement *pElement)
  393. {
  394. assert (pElement != nullptr);
  395. if (pElement != nullptr)
  396. m_ElementArr.append(*pElement);
  397. }
  398. void CConfigSchemaHelper::processElementArr()
  399. {
  400. int length = m_nodeWithBaseArr.length();
  401. for (int idx = 0; idx < length; idx++)
  402. {
  403. CElement *pElement = &(this->m_ElementArr.item(idx));
  404. const char *pRef = pElement->getRef();
  405. assert(pRef != nullptr);
  406. if (pRef != nullptr)
  407. {
  408. CElement *pRefElementNode = nullptr;
  409. pRefElementNode = m_pSchemaMapManager->getElementWithName(pRef);
  410. if (pRefElementNode != nullptr)
  411. pElement->setRefElementNode(pRefElementNode);
  412. else
  413. //TODO: throw exception
  414. assert(!"Unknown element referenced");
  415. }
  416. }
  417. m_ElementArr.popAll(false);
  418. }
  419. void CConfigSchemaHelper::populateEnvXPath()
  420. {
  421. CSchema* pSchema = nullptr;
  422. StringBuffer strXPath;
  423. LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
  424. {
  425. pSchema = m_pSchemaMapManager->getSchemaForXSD(CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx));
  426. if (pSchema != nullptr)
  427. pSchema->populateEnvXPath(strXPath);
  428. }
  429. }
  430. void CConfigSchemaHelper::loadEnvFromConfig(const char *pEnvFile)
  431. {
  432. assert(pEnvFile != nullptr);
  433. typedef ::IPropertyTree PT;
  434. Linked<PT> pEnvXMLRoot;
  435. try
  436. {
  437. pEnvXMLRoot.setown(createPTreeFromXMLFile(pEnvFile));
  438. }
  439. catch (...)
  440. {
  441. CONFIGURATOR::MakeExceptionFromMap(EX_STR_CAN_NOT_PROCESS_ENV_XML);
  442. }
  443. CSchema* pSchema = nullptr;
  444. this->setEnvPropertyTree(pEnvXMLRoot.getLink());
  445. this->setEnvFilePath(pEnvFile);
  446. LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
  447. {
  448. pSchema = m_pSchemaMapManager->getSchemaForXSD(CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx));
  449. if (pSchema != nullptr)
  450. pSchema->loadXMLFromEnvXml(pEnvXMLRoot);
  451. }
  452. }
  453. void CConfigSchemaHelper::setEnvTreeProp(const char *pXPath, const char* pValue)
  454. {
  455. assert(pXPath != nullptr && pXPath[0] != 0);
  456. assert(m_pSchemaMapManager != nullptr);
  457. CAttribute *pAttribute = m_pSchemaMapManager->getAttributeFromXPath(pXPath);
  458. assert(pAttribute != nullptr);
  459. StringBuffer strPropName("@");
  460. strPropName.append(pAttribute->getName());
  461. if (this->getEnvPropertyTree()->queryPropTree(pAttribute->getConstAncestorNode(1)->getEnvXPath())->queryProp(strPropName.str()) == nullptr)
  462. //should check if this attribute is optional for validation
  463. this->getEnvPropertyTree()->queryPropTree(pAttribute->getConstAncestorNode(1)->getEnvXPath())->setProp(strPropName.str(), pValue);
  464. else if (strcmp (this->getEnvPropertyTree()->queryPropTree(pAttribute->getConstAncestorNode(1)->getEnvXPath())->queryProp(strPropName.str()), pValue) == 0)
  465. return; // nothing changed
  466. else
  467. this->getEnvPropertyTree()->queryPropTree(pAttribute->getConstAncestorNode(1)->getEnvXPath())->setProp(strPropName.str(), pValue);
  468. }
  469. const char* CConfigSchemaHelper::getTableValue(const char* pXPath, int nRow) const
  470. {
  471. assert(pXPath != nullptr);
  472. assert(m_pSchemaMapManager != nullptr);
  473. CAttribute *pAttribute = m_pSchemaMapManager->getAttributeFromXPath(pXPath);
  474. CElement *pElement = nullptr;
  475. if (pAttribute == nullptr)
  476. {
  477. pElement = m_pSchemaMapManager->getElementFromXPath(pXPath);
  478. assert(pElement != nullptr);
  479. return pElement->getEnvValueFromXML();
  480. }
  481. else
  482. {
  483. assert(pAttribute != nullptr);
  484. if (nRow == 1)
  485. return pAttribute->getEnvValueFromXML();
  486. else
  487. {
  488. StringBuffer strXPath(pXPath);
  489. StringBuffer strXPathOrignal(pXPath);
  490. CConfigSchemaHelper::stripXPathIndex(strXPath);
  491. strXPath.appendf("[%d]", nRow);
  492. char pTemp[64];
  493. int offset = strXPath.length() - (strlen(itoa(nRow, pTemp, 10)) - 1);
  494. strXPath.append(strXPathOrignal, strXPath.length(), strXPathOrignal.length()-offset);
  495. pAttribute = m_pSchemaMapManager->getAttributeFromXPath(strXPath.str());
  496. if (pAttribute == nullptr)
  497. return nullptr;
  498. return pAttribute->getEnvValueFromXML();
  499. }
  500. }
  501. }
  502. int CConfigSchemaHelper::getElementArraySize(const char *pXPath) const
  503. {
  504. assert(pXPath != nullptr);
  505. assert(m_pSchemaMapManager != nullptr);
  506. CElementArray *pElementArray = m_pSchemaMapManager->getElementArrayFromXPath(pXPath);
  507. if (pElementArray == nullptr)
  508. return 0;
  509. VStringBuffer strXPath("%s[1]",pElementArray->getXSDXPath());
  510. return pElementArray->getCountOfSiblingElements(strXPath.str());
  511. }
  512. const char* CConfigSchemaHelper::getAttributeXSDXPathFromEnvXPath(const char* pEnvXPath) const
  513. {
  514. assert(pEnvXPath != nullptr && *pEnvXPath != 0);
  515. assert(m_pSchemaMapManager != nullptr);
  516. CAttribute *pAttribute = m_pSchemaMapManager->getAttributeFromXPath(pEnvXPath);
  517. assert(pAttribute != nullptr);
  518. return pAttribute->getXSDXPath();
  519. }
  520. const char* CConfigSchemaHelper::getElementArrayXSDXPathFromEnvXPath(const char* pXSDXPath) const
  521. {
  522. assert(pXSDXPath != nullptr);
  523. assert(m_pSchemaMapManager != nullptr);
  524. CElementArray *pElementArray = m_pSchemaMapManager->getElementArrayFromXSDXPath(pXSDXPath);
  525. assert(pElementArray != nullptr);
  526. return pElementArray->getXSDXPath();
  527. }
  528. void CConfigSchemaHelper::appendAttributeXPath(const char* pXPath)
  529. {
  530. m_strArrayEnvXPaths.append(pXPath);
  531. }
  532. void CConfigSchemaHelper::appendElementXPath(const char* pXPath)
  533. {
  534. m_strArrayEnvXPaths.append(pXPath);
  535. }
  536. size_t CConfigSchemaHelper::getXPathIndexLength(const char *pXPath)
  537. {
  538. if (!pXPath || !pXPath)
  539. return 0;
  540. size_t length = strlen(pXPath);
  541. if (length < 4) // min length must be atleast 4 : T[N]
  542. return 0;
  543. const char *pFinger = &(pXPath[length-1]);
  544. while (pFinger != pXPath && *pFinger != '[')
  545. {
  546. pFinger--;
  547. }
  548. return (pFinger == pXPath ? 0 : &(pXPath[length]) - pFinger);
  549. }
  550. int CConfigSchemaHelper::stripXPathIndex(StringBuffer &strXPath)
  551. {
  552. int nStripped = getXPathIndexLength(strXPath.str());
  553. strXPath.setLength(strXPath.length()-nStripped);
  554. return nStripped;
  555. }
  556. bool CConfigSchemaHelper::isXPathTailAttribute(const StringBuffer &strXPath)
  557. {
  558. int nLen = strXPath.length()-3;
  559. while (nLen > 0)
  560. {
  561. if (strXPath[nLen] == '[')
  562. {
  563. if (strXPath[nLen+1] == '@')
  564. return true;
  565. else
  566. return false;
  567. }
  568. nLen--;
  569. }
  570. assert(!"Control should not reach here");
  571. return false;
  572. }
  573. void CConfigSchemaHelper::setBasePath(const char *pBasePath)
  574. {
  575. assert(m_pBasePath == nullptr);
  576. int nLength = strlen(pBasePath);
  577. m_pBasePath = new char[nLength+1];
  578. strcpy(m_pBasePath, pBasePath);
  579. }
  580. bool CConfigSchemaHelper::saveConfigurationFile() const
  581. {
  582. assert(m_strEnvFilePath.length() != 0);
  583. if (m_strEnvFilePath.length() == 0)
  584. return false;
  585. if (this->getConstEnvPropertyTree() == nullptr)
  586. return false;
  587. StringBuffer strXML;
  588. strXML.appendf("<" XML_HEADER ">\n<!-- Edited with THE CONFIGURATOR -->\n");
  589. ::toXML(this->getConstEnvPropertyTree(), strXML, 0, XML_SortTags | XML_Format);
  590. if (CConfigFileUtils::getInstance()->writeConfigurationToFile(m_strEnvFilePath.str(), strXML.str(), strXML.length()) == CConfigFileUtils::CF_NO_ERROR)
  591. return true;
  592. else
  593. return false;
  594. }
  595. bool CConfigSchemaHelper::saveConfigurationFileAs(const char *pFilePath)
  596. {
  597. assert(pFilePath && *pFilePath);
  598. if (pFilePath == nullptr || *pFilePath == 0)
  599. return false;
  600. if (this->getConstEnvPropertyTree() == nullptr)
  601. return false;
  602. StringBuffer strXML;
  603. strXML.appendf("<" XML_HEADER ">\n<!-- Edited with THE CONFIGURATOR -->\n");
  604. ::toXML(this->getConstEnvPropertyTree(), strXML, 0, XML_SortTags | XML_Format);
  605. if (CConfigFileUtils::getInstance()->writeConfigurationToFile(pFilePath, strXML.str(), strXML.length()) == CConfigFileUtils::CF_NO_ERROR)
  606. {
  607. m_strEnvFilePath.set(pFilePath);
  608. return true;
  609. }
  610. else
  611. return false;
  612. }
  613. void CConfigSchemaHelper::addKeyRefForReverseAssociation(const CKeyRef *pKeyRef) const
  614. {
  615. }
  616. void CConfigSchemaHelper::processKeyRefReverseAssociation() const
  617. {
  618. }
  619. void CConfigSchemaHelper::addKeyForReverseAssociation(const CKey *pKeyRef) const
  620. {
  621. }
  622. void CConfigSchemaHelper::processKeyReverseAssociation() const
  623. {
  624. }
  625. int CConfigSchemaHelper::getInstancesOfComponentType(const char *pCompType) const
  626. {
  627. assert(pCompType != nullptr && *pCompType != 0);
  628. LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
  629. {
  630. const char *pCompName = CBuildSetManager::getInstance()->getBuildSetComponentTypeName(idx);// ->getBuildSetProcessName(idx);
  631. const char *pProcessName = CBuildSetManager::getInstance()->getBuildSetProcessName(idx);
  632. if (pCompName != nullptr && strcmp(pCompName, pCompType) == 0)
  633. {
  634. CSchema *pSchema = m_pSchemaMapManager->getSchemaForXSD(CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx));
  635. assert(pSchema != nullptr);
  636. if (pSchema == nullptr)
  637. return FAILURE;
  638. int nCount = 0;
  639. ::VStringBuffer strXPath("./%s/%s[%d]", XML_TAG_SOFTWARE, pProcessName, 1);
  640. while (true)
  641. {
  642. ::IPropertyTree *pTree = CConfigSchemaHelper::getInstance()->getEnvPropertyTree();
  643. if (pTree == nullptr)
  644. return FAILURE;
  645. if (pTree->queryPropTree(strXPath.str()) == nullptr)
  646. return nCount;
  647. nCount++;
  648. strXPath.setf("./%s/%s[%d]", XML_TAG_SOFTWARE, pProcessName, nCount+1);
  649. }
  650. }
  651. }
  652. return SUCCESS;
  653. }
  654. const char* CConfigSchemaHelper::getInstanceNameOfComponentType(const char *pCompType, int idx)
  655. {
  656. if (pCompType == nullptr || *pCompType == 0)
  657. return nullptr; // throw exception?
  658. if (this->getEnvPropertyTree() == nullptr)
  659. return nullptr; // throw exception?
  660. ::VStringBuffer strXPath("./%s/%s[%d]", XML_TAG_SOFTWARE, pCompType, idx+1);
  661. typedef ::IPropertyTree jlibIPropertyTree;
  662. const ::IPropertyTree *pTree = const_cast<const jlibIPropertyTree*>(this->getEnvPropertyTree()->queryPropTree(strXPath.str()));
  663. return pTree->queryProp(XML_ATTR_NAME);
  664. }
  665. void CConfigSchemaHelper::clearLF(::StringBuffer& strToClear)
  666. {
  667. strToClear.replaceString("\n","");
  668. }
  669. CConfigSchemaHelper* CConfigSchemaHelper::getNewInstance(const char* pDefaultDirOverride)
  670. {
  671. if (CConfigSchemaHelper::s_pCConfigSchemaHelper != nullptr)
  672. {
  673. delete CConfigSchemaHelper::s_pCConfigSchemaHelper;
  674. CConfigSchemaHelper::s_pCConfigSchemaHelper = nullptr;
  675. }
  676. CConfigSchemaHelper::getInstance(pDefaultDirOverride);
  677. CConfigSchemaHelper::getInstance()->populateSchema();
  678. return CConfigSchemaHelper::getInstance();
  679. }