SchemaKey.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*##############################################################################
  2. *
  3. HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. ############################################################################## */
  14. #include "jptree.hpp"
  15. #include "SchemaKey.hpp"
  16. #include "SchemaSelector.hpp"
  17. #include "SchemaField.hpp"
  18. #include "SchemaAnnotation.hpp"
  19. #include "SchemaCommon.hpp"
  20. #include "ConfigSchemaHelper.hpp"
  21. #include "SchemaMapManager.hpp"
  22. #include "SchemaAttributes.hpp"
  23. using namespace CONFIGURATOR;
  24. #define IPropertyTree ::IPropertyTree
  25. CKey* CKey::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
  26. {
  27. assert(pSchemaRoot != nullptr);
  28. assert(pParentNode != nullptr);
  29. assert(pParentNode->getNodeType() == XSD_KEY_ARRAY);
  30. if (pSchemaRoot == nullptr || pParentNode == nullptr)
  31. {
  32. // TODO: Throw Exception
  33. return nullptr;
  34. }
  35. CKey *pKey = new CKey(pParentNode);
  36. if (xpath != nullptr && *xpath != 0)
  37. {
  38. IPropertyTree* pTree = pSchemaRoot->queryPropTree(xpath);
  39. if (pTree == nullptr)
  40. return nullptr; // no xs:key
  41. const char* pName = pTree->queryProp(XML_ATTR_NAME);
  42. if (pName != nullptr)
  43. {
  44. pKey->setXSDXPath(xpath);
  45. pKey->setName(pName);
  46. }
  47. else
  48. {
  49. assert(!"value attribute can be empty!");
  50. delete pKey;
  51. // TODO: throw MakeExceptionFromMap(EX_STR_MISSING_VALUE_ATTRIBUTE_IN_LENGTH);
  52. return nullptr;
  53. }
  54. const char *pID = pTree->queryProp(XML_ATTR_ID);
  55. if (pID != nullptr)
  56. pKey->setID(pID);
  57. StringBuffer strXPathExt(xpath);
  58. strXPathExt.append("/").append(XSD_TAG_FIELD);
  59. if (strXPathExt.charAt(0) == '@')
  60. strXPathExt.remove(0,1); // remove '@'
  61. pKey->m_pFieldArray = CFieldArray::load(pKey, pSchemaRoot, strXPathExt.str());
  62. strXPathExt.set(xpath);
  63. strXPathExt.append("/").append(XSD_TAG_SELECTOR);
  64. if (strXPathExt.charAt(0) == '.')
  65. strXPathExt.remove(0,2); // remove leading ./
  66. pKey->m_pSelector = CSelector::load(pKey, pSchemaRoot, strXPathExt.str());
  67. assert(pKey->m_pFieldArray != nullptr && pKey->m_pSelector != nullptr);
  68. strXPathExt.append("/").append(XSD_TAG_ANNOTATION);
  69. pKey->m_pAnnotation = CAnnotation::load(pKey, pSchemaRoot, strXPathExt.str());
  70. }
  71. return pKey;
  72. }
  73. void CKey::populateEnvXPath(StringBuffer strXPath, unsigned int index)
  74. {
  75. assert(this->m_pSelector != nullptr);
  76. this->setEnvXPath(strXPath.str());
  77. if (this->m_pSelector != nullptr)
  78. {
  79. this->m_pSelector->populateEnvXPath(strXPath.str());
  80. CConfigSchemaHelper::getInstance()->addKeyForReverseAssociation(this);
  81. }
  82. }
  83. bool CKey::checkConstraint(const char *pValue) const
  84. {
  85. bool bRetVal = true;
  86. auto fieldArraylength = m_pFieldArray->length();
  87. if (m_pSelector != nullptr && fieldArraylength != 0)
  88. {
  89. for (int idx = 0; idx < fieldArraylength; idx++)
  90. {
  91. assert(!"Multiple fields not implemented");
  92. CField *m_pField = &(m_pFieldArray->item(idx));
  93. assert(m_pField != nullptr);
  94. if (m_pField == nullptr)
  95. return false;
  96. StringBuffer strXPathForConstraintCheck(this->getEnvXPath());
  97. strXPathForConstraintCheck.appendf("/%s", this->m_pSelector->getXPath());
  98. const CElement *pElement = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getElementFromXPath(strXPathForConstraintCheck.str());
  99. if (pElement == nullptr)
  100. return false;
  101. const CAttribute *pAttribute = dynamic_cast<const CAttribute*>(pElement->getNodeByTypeAndNameDescending(XSD_ATTRIBUTE, m_pField->getXPath())); // needs to be first possible descendent
  102. if (pAttribute != nullptr && pAttribute->getParentNodeByType(XSD_ELEMENT) != pElement)
  103. {
  104. assert(!"Could not find match for key");
  105. }
  106. }
  107. }
  108. return bRetVal;
  109. }
  110. void CKey::dump(::std::ostream& cout, unsigned int offset) const
  111. {
  112. offset += STANDARD_OFFSET_1;
  113. quickOutHeader(cout, XSD_KEY_STR, offset);
  114. QUICK_OUT(cout, Name, offset);
  115. QUICK_OUT(cout, ID, offset);
  116. QUICK_OUT(cout, XSDXPath, offset);
  117. if (m_pFieldArray != nullptr)
  118. m_pFieldArray->dump(cout, offset);
  119. if (m_pSelector != nullptr)
  120. m_pSelector->dump(cout, offset);
  121. quickOutFooter(cout, XSD_KEY_STR, offset);
  122. }
  123. CKeyArray* CKeyArray::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
  124. {
  125. assert(pSchemaRoot != nullptr);
  126. assert(pParentNode->getNodeType() == XSD_ELEMENT);
  127. if (pSchemaRoot == nullptr || xpath == nullptr)
  128. return nullptr;
  129. StringBuffer strXPathExt(xpath);
  130. CKeyArray *pKeyArray = new CKeyArray(pParentNode);
  131. pKeyArray->setXSDXPath(xpath);
  132. Owned<IPropertyTreeIterator> attributeIter = pSchemaRoot->getElements(xpath, ipt_ordered);
  133. int count = 1;
  134. ForEach(*attributeIter)
  135. {
  136. strXPathExt.clear().append(xpath).appendf("[%d]",count);
  137. CKey *pKey = CKey::load(pKeyArray, pSchemaRoot, strXPathExt.str());
  138. if (pKey != nullptr)
  139. pKeyArray->append(*pKey);
  140. count++;
  141. }
  142. if (pKeyArray->length() == 0)
  143. {
  144. delete pKeyArray;
  145. pKeyArray = nullptr;
  146. }
  147. return pKeyArray;
  148. }
  149. bool CKeyArray::checkConstraint(const char *pValue) const
  150. {
  151. assert(pValue != nullptr);
  152. if (pValue == nullptr)
  153. return false;
  154. for (int idx = 0; idx < this->length(); idx++)
  155. {
  156. if ((this->item(idx)).checkConstraint(pValue) == false)
  157. return false;
  158. }
  159. return true;
  160. }
  161. void CKeyArray::dump(::std::ostream &cout, unsigned int offset) const
  162. {
  163. offset+= STANDARD_OFFSET_1;
  164. quickOutHeader(cout, XSD_KEY_ARRAY_STR, offset);
  165. QUICK_OUT(cout, XSDXPath, offset);
  166. QUICK_OUT(cout, EnvXPath, offset);
  167. QUICK_OUT_ARRAY(cout, offset);
  168. quickOutFooter(cout, XSD_KEY_ARRAY_STR, offset);
  169. }
  170. void CKeyArray::populateEnvXPath(StringBuffer strXPath, unsigned int index)
  171. {
  172. this->setEnvXPath(strXPath);
  173. QUICK_ENV_XPATH_WITH_INDEX(strXPath, index)
  174. }