{"action":"created","comment":{"url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/comments/73395855","id":73395855,"diff_hunk":"@@ -0,0 +1,887 @@\n+/*##############################################################################\n+\n+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.\n+\n+    Licensed under the Apache License, Version 2.0 (the \"License\");\n+    you may not use this file except in compliance with the License.\n+    You may obtain a copy of the License at\n+\n+       http://www.apache.org/licenses/LICENSE-2.0\n+\n+    Unless required by applicable law or agreed to in writing, software\n+    distributed under the License is distributed on an \"AS IS\" BASIS,\n+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+    See the License for the specific language governing permissions and\n+    limitations under the License.\n+############################################################################## */\n+\n+#include <cassert>\n+#include \"jptree.hpp\"\n+#include \"jstring.hpp\"\n+#include \"jarray.hpp\"\n+#include \"jhash.hpp\"\n+#include \"XMLTags.h\"\n+\n+\n+//#define ::StringBuffer ::::StringBuffer\n+//#define ::IPropertyTree ::::IPropertyTree\n+\n+#include \"SchemaAnnotation.hpp\"\n+#include \"SchemaCommon.hpp\"\n+#include \"SchemaElement.hpp\"\n+#include \"SchemaComplexType.hpp\"\n+#include \"SchemaElement.hpp\"\n+#include \"SchemaAttributes.hpp\"\n+#include \"SchemaAppInfo.hpp\"\n+#include \"SchemaDocumentation.hpp\"\n+#include \"DocumentationMarkup.hpp\"\n+#include \"ConfigSchemaHelper.hpp\"\n+#include \"ConfigSchemaHelper.hpp\"\n+#include \"SchemaMapManager.hpp\"\n+#include \"ConfiguratorMain.hpp\"\n+#include \"JSONMarkUp.hpp\"\n+\n+using namespace CONFIGURATOR;\n+\n+const CXSDNodeBase* CElement::getNodeByTypeAndNameAscending(NODE_TYPES eNodeType, const char *pName) const\n+{\n+    const CXSDNodeBase* pMatchingNode = NULL;\n+\n+    if (eNodeType == this->getNodeType() && (pName != NULL ? !strcmp(pName, this->getNodeTypeStr()) : true))\n+        return this;\n+\n+    if (eNodeType == XSD_ELEMENT)\n+        pMatchingNode = (dynamic_cast<CElement*>(this->getParentNode()))->getNodeByTypeAndNameAscending(XSD_ELEMENT, pName);\n+    if (pMatchingNode == NULL)\n+        pMatchingNode = (dynamic_cast<CElementArray*>(this->getParentNode()))->getNodeByTypeAndNameAscending(eNodeType, pName);\n+\n+    return pMatchingNode;\n+}\n+\n+const CXSDNodeBase* CElement::getNodeByTypeAndNameDescending(NODE_TYPES eNodeType, const char *pName) const\n+{\n+    const CXSDNodeBase* pMatchingNode = NULL;\n+\n+    if (eNodeType == this->getNodeType() && (pName != NULL ? !strcmp(pName, this->getNodeTypeStr()) : true))\n+        return this;\n+    if (m_pComplexTypeArray != NULL)\n+        pMatchingNode = m_pComplexTypeArray->getNodeByTypeAndNameDescending(eNodeType, pName);\n+\n+    return pMatchingNode;\n+}\n+\n+CElement* CElement::load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath, bool bIsInXSD)\n+{\n+    assert(pSchemaRoot != NULL);\n+    assert(pParentNode != NULL);\n+\n+    if (pSchemaRoot == NULL || pParentNode == NULL)\n+        return NULL;\n+\n+    CElement *pElement = new CElement(pParentNode);\n+\n+    pElement->setIsInXSD(bIsInXSD);\n+    pElement->setXSDXPath(xpath);\n+\n+    ::IPropertyTree *pTree = pSchemaRoot->queryPropTree(xpath);\n+\n+    if (pElement != NULL && pTree != NULL)\n+        pElement->setName(pTree->queryProp(XML_ATTR_NAME));\n+\n+    Owned<IAttributeIterator> iterAttrib = pTree->getAttributes(true);\n+\n+    ForEach(*iterAttrib)\n+    {\n+        if (strcmp(iterAttrib->queryName(), XML_ATTR_NAME) == 0)\n+        {\n+            const char *pName = iterAttrib->queryValue();\n+\n+            if (pName != NULL && *pName != 0)\n+                pElement->setName(pName);\n+        }\n+        else if (strcmp(iterAttrib->queryName(), XML_ATTR_MAXOCCURS) == 0)\n+            pElement->setMaxOccurs(iterAttrib->queryValue());\n+        else if (strcmp(iterAttrib->queryName(), XML_ATTR_MINOCCURS) == 0)\n+            pElement->setMinOccurs(iterAttrib->queryValue());\n+        else if (strcmp(iterAttrib->queryName(), XML_ATTR_TYPE) == 0)\n+        {\n+            const char *pType = iterAttrib->queryValue();\n+\n+            assert(pType != NULL && *pType != 0);\n+\n+            if (pType != NULL && *pType != 0)\n+            {\n+                pElement->setType(pType);\n+                CConfigSchemaHelper::getInstance()->addNodeForTypeProcessing(pElement);\n+            }\n+        }\n+        else if (strcmp(iterAttrib->queryName(), XML_ATTR_REF) == 0)\n+        {\n+            const char *pRef = iterAttrib->queryValue();\n+\n+            assert (pRef != NULL && *pRef != 0 && pElement->getConstAncestorNode(3)->getNodeType() != XSD_SCHEMA);\n+\n+            if (pRef != NULL && *pRef != 0 && pElement->getConstAncestorNode(3)->getNodeType() != XSD_SCHEMA)\n+            {\n+                pElement->setRef(pRef);\n+                CConfigSchemaHelper::getInstance()->addElementForRefProcessing(pElement);\n+            }\n+            else\n+            {\n+                // TODO:  throw exception\n+            }\n+        }\n+        else if (strcmp(iterAttrib->queryName(), XML_ATTR_DEFAULT) == 0)\n+        {\n+            const char *pDefault = iterAttrib->queryValue();\n+\n+            assert(pDefault != NULL);\n+            assert(strlen(pElement->getDefault()) == 0);\n+            pElement->setDefault(pDefault);\n+        }\n+        assert(iterAttrib->queryValue() != NULL);\n+    }\n+    assert(strlen(pElement->getName()) > 0);\n+\n+    if (strlen(pElement->getRef()) != 0)\n+    {\n+        assert(pElement->getComplexTypeArray()->length() == 0);\n+        assert(pElement->getSimpleType() == NULL);\n+        assert(strlen(pElement->getDefault()) == 0);\n+        assert(strlen(pElement->getType()) == 0);\n+        /*assert(pElement->getKey() == NULL);\n+        assert(pElement->getKeyRef() == NULL);\n+        assert(pElement->getUnique() == NULL);*/\n+    }\n+\n+    ::StringBuffer strXPathExt(xpath);\n+\n+    strXPathExt.append(\"/\").append(XSD_TAG_ANNOTATION);\n+    pElement->m_pAnnotation = CAnnotation::load(pElement, pSchemaRoot, strXPathExt.str());\n+\n+    strXPathExt.clear().append(xpath).append(\"/\").append(XSD_TAG_COMPLEX_TYPE);\n+    pElement->m_pComplexTypeArray = CComplexTypeArray::load(pElement, pSchemaRoot, strXPathExt.str());\n+\n+    if (pElement->m_pAnnotation != NULL && pElement->m_pAnnotation->getAppInfo() != NULL && strlen(pElement->m_pAnnotation->getAppInfo()->getTitle()) > 0)\n+    {\n+        /****  MUST FIX TO HAVE CORRECT UI TAB LABELS (but getName is expected to return the XPATH name *****/\n+        //pElement->setName(pElement->m_pAnnotation->getAppInfo()->getTitle());\n+        pElement->setTitle(pElement->m_pAnnotation->getAppInfo()->getTitle());\n+    }\n+    else\n+        pElement->setTitle(pElement->getName());\n+\n+/*    strXPathExt.clear().append(xpath).append(\"/\").append(XSD_TAG_KEY);\n+    pElement->m_pKeyArray = CKeyArray::load(pElement, pSchemaRoot, strXPathExt.str());\n+\n+    strXPathExt.clear().append(xpath).append(\"/\").append(XSD_TAG_KEYREF);\n+    pElement->m_pKeyRefArray = CKeyRefArray::load(pElement, pSchemaRoot, strXPathExt.str());\n+*/\n+    strXPathExt.clear().append(xpath).append(\"/\").append(XSD_TAG_SIMPLE_TYPE);\n+    pElement->m_pSimpleType = CSimpleType::load(pElement, pSchemaRoot, strXPathExt.str());\n+\n+    SETPARENTNODE(pElement, pParentNode);\n+\n+    return pElement;\n+}\n+\n+const CElement* CElement::getTopMostElement(const CXSDNodeBase *pNode)\n+{\n+    if (pNode == NULL)\n+        return NULL;\n+    else if (pNode->getNodeType() == XSD_ELEMENT)\n+    {\n+        if (pNode->getParentNodeByType(XSD_ELEMENT) == NULL)\n+        {\n+            assert(dynamic_cast<const CElement*>(pNode) != NULL);\n+            return dynamic_cast<const CElement*>(pNode);\n+        }\n+    }\n+    return getTopMostElement(pNode->getParentNodeByType(XSD_ELEMENT));\n+}\n+\n+const CSchema* CElement::getConstSchemaNode() const\n+{\n+    const CSchema *pSchema = dynamic_cast<const CSchema*>(CElement::getTopMostElement(this)->getParentNodeByType(XSD_SCHEMA));\n+    return pSchema;\n+}\n+\n+const char* CElement::getXML(const char* /*pComponent*/)\n+{\n+    if (m_strXML.length () == 0)\n+    {\n+        m_strXML.append(\"\\n<\").append(getName()).append(\" \");\n+\n+        if (m_pAnnotation != NULL)\n+            m_strXML.append(m_pAnnotation->getXML(NULL));\n+        if (m_pComplexTypeArray != NULL)\n+            m_strXML.append(m_pComplexTypeArray->getXML(NULL));\n+        if (m_pKeyArray != NULL)\n+            m_strXML.append(m_pKeyArray->getXML(NULL));\n+        if (m_pKeyRefArray != NULL)\n+            m_strXML.append(m_pKeyRefArray->getXML(NULL));\n+    }\n+    return m_strXML.str();\n+}\n+\n+void CElement::dump(::std::ostream &cout, unsigned int offset) const\n+{\n+    offset += STANDARD_OFFSET_1;\n+\n+    QuickOutHeader(cout, XSD_ELEMENT_STR, offset);\n+    QUICK_OUT(cout, Name, offset);\n+    QUICK_OUT(cout, Type, offset);\n+    QUICK_OUT(cout, MinOccurs, offset);\n+    QUICK_OUT(cout, MaxOccurs, offset);\n+    QUICK_OUT(cout, Title,  offset);\n+    QUICK_OUT(cout, XSDXPath,  offset);\n+    QUICK_OUT(cout, EnvXPath,  offset);\n+    QUICK_OUT(cout, EnvValueFromXML,  offset);\n+    QUICK_OUT(cout, Ref, offset);\n+\n+    if (this->getTypeNode() != NULL)\n+        this->getTypeNode()->dump(cout, offset);\n+    if (m_pAnnotation != NULL)\n+        m_pAnnotation->dump(cout, offset);\n+    if (m_pComplexTypeArray != NULL)\n+        m_pComplexTypeArray->dump(cout, offset);\n+    if (m_pKeyArray != NULL)\n+        m_pKeyArray->dump(cout, offset);\n+    if (m_pKeyRefArray != NULL)\n+        m_pKeyRefArray->dump(cout, offset);\n+    if (m_pSimpleType != NULL)\n+        m_pSimpleType->dump(cout, offset);\n+\n+    if (this->getRef() != NULL)\n+    {\n+        CElement *pElement = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getElementWithName(this->getRef());\n+\n+        assert(pElement != NULL);\n+        if (pElement != NULL)\n+            pElement->dump(cout, offset);\n+    }\n+    QuickOutFooter(cout, XSD_ELEMENT_STR, offset);\n+}\n+\n+void CElement::getDocumentation(::StringBuffer &strDoc) const\n+{\n+    const CXSDNodeBase *pGrandParentNode = this->getConstParentNode()->getConstParentNode();\n+\n+    assert(pGrandParentNode != NULL);\n+    if (pGrandParentNode == NULL)\n+        return;\n+\n+    if (m_pAnnotation != NULL && m_pAnnotation->getAppInfo() != NULL && m_pAnnotation->getAppInfo()->getViewType() != NULL && stricmp(m_pAnnotation->getAppInfo()->getViewType(), \"none\") == 0)\n+        return;\n+\n+    if (this->getName() != NULL && (stricmp(this->getName(), \"Instance\") == 0 || stricmp(this->getName(), \"Note\") == 0 || stricmp(this->getName(), \"Notes\") == 0 ||  stricmp(this->getName(), \"Topology\") == 0 ))\n+        return; // don't document instance\n+\n+    assert(strlen(this->getName()) > 0);\n+\n+    if (pGrandParentNode->getNodeType() == XSD_SCHEMA)\n+    {\n+        ::StringBuffer strName(this->getName());\n+\n+        strName.replace(' ', '_');\n+        strDoc.append(DM_HEADING);\n+\n+        // component name would be here\n+        strDoc.appendf(\"<%s %s=\\\"%s%s\\\">\\n\", DM_SECT2, DM_ID, strName.str(),\"_mod\");\n+        strDoc.appendf(\"<%s>%s</%s>\\n\", DM_TITLE_LITERAL, this->getName(), DM_TITLE_LITERAL);\n+\n+        if (m_pAnnotation!= NULL)\n+        {\n+            m_pAnnotation->getDocumentation(strDoc);\n+            DEBUG_MARK_STRDOC;\n+        }\n+\n+        strDoc.append(DM_SECT3_BEGIN);\n+        DEBUG_MARK_STRDOC;\n+        strDoc.append(DM_TITLE_BEGIN).append(DM_TITLE_END);\n+\n+        if (m_pComplexTypeArray != NULL)\n+            m_pComplexTypeArray->getDocumentation(strDoc);\n+\n+        strDoc.append(DM_SECT3_END);\n+        return;\n+    }\n+    else if (m_pComplexTypeArray != NULL)\n+    {\n+        if (m_pAnnotation!= NULL)\n+        {\n+            m_pAnnotation->getDocumentation(strDoc);\n+            DEBUG_MARK_STRDOC;\n+        }\n+\n+        if (pGrandParentNode->getNodeType() == XSD_CHOICE)\n+            strDoc.appendf(\"%s%s%s\", DM_PARA_BEGIN, this->getTitle(), DM_PARA_END);\n+        else\n+            strDoc.appendf(\"%s%s%s\", DM_TITLE_BEGIN, this->getTitle(), DM_TITLE_END);\n+\n+        DEBUG_MARK_STRDOC;\n+        m_pComplexTypeArray->getDocumentation(strDoc);\n+    }\n+    else if (m_pComplexTypeArray == NULL)\n+    {\n+        if (m_pAnnotation!= NULL)\n+        {\n+            m_pAnnotation->getDocumentation(strDoc);\n+            DEBUG_MARK_STRDOC;\n+        }\n+\n+        strDoc.appendf(\"%s%s%s\", DM_PARA_BEGIN, this->getName(), DM_PARA_END);\n+        DEBUG_MARK_STRDOC;\n+\n+        if (m_pAnnotation != NULL && m_pAnnotation->getDocumentation() != NULL)\n+        {\n+            m_pAnnotation->getDocumentation(strDoc);\n+            DEBUG_MARK_STRDOC;\n+        }\n+    }\n+}\n+\n+void CElement::getJSON(::StringBuffer &strJSON, unsigned int offset, int idx) const\n+{\n+    assert(this->getConstAncestorNode(3) != NULL);\n+\n+//    if (m_pAnnotation != NULL && m_pAnnotation->getAppInfo() != NULL && m_pAnnotation->getAppInfo()->getViewType() != NULL && stricmp(m_pAnnotation->getAppInfo()->getViewType(), \"none\") == 0)\n+//        return;\n+\n+    assert(strlen(this->getName()) > 0);\n+\n+    StringBuffer strXPath(this->getEnvXPath());\n+\n+    stripTrailingIndex(strXPath);\n+\n+    if (m_pComplexTypeArray != NULL  && m_pComplexTypeArray->length() > 0)\n+    {\n+        //CJSONMarkUpHelper::createUIContent(strJSON, offset, (this->getMaxOccursInt() > 1 || strlen(this->getMinOccurs()) > 0) ? JSON_TYPE_TABLE : JSON_TYPE_TAB, this->getTitle(), this->getEnvXPath());\n+\n+        //CJSONMarkUpHelper::createUIContent(strJSON, offset, (this->getMaxOccursInt() > 1 || strlen(this->getMinOccurs()) > 0) ? JSON_TYPE_TABLE : JSON_TYPE_TAB, this->getTitle(), strXPath.str());\n+        CJSONMarkUpHelper::createUIContent(strJSON, offset, JSON_TYPE_TAB, this->getTitle(), strXPath.str());\n+\n+        m_pComplexTypeArray->getJSON(strJSON, offset);\n+    }\n+    else\n+    {\n+        //CJSONMarkUpHelper::createUIContent(strJSON, offset, JSON_TYPE_TABLE, this->getTitle(), this->getEnvXPath());\n+        CJSONMarkUpHelper::createUIContent(strJSON, offset, JSON_TYPE_TABLE, this->getTitle(), strXPath.str());\n+        // add values\n+        //CJSONMarkUpHelper::createUIContent(strJSON, offset, JSON_TYPE_INPUT, this->getTitle(),  strXPath.str());\n+    }\n+}\n+\n+\n+bool CElement::isATab() const\n+{\n+    const CComplexTypeArray *pComplexTypArray = this->getComplexTypeArray();\n+    const CAttributeGroupArray *pAttributeGroupArray = (pComplexTypArray != NULL && pComplexTypArray->length() > 0) ? pComplexTypArray->item(0).getAttributeGroupArray() : NULL;\n+    const CAttributeArray *pAttributeArray = (pComplexTypArray != NULL && pComplexTypArray->length() > 0) ? pComplexTypArray->item(0).getAttributeArray() : NULL;\n+\n+    if (this->getConstAncestorNode(3)->getNodeType() != XSD_SCHEMA && \\\n+            (this->hasChildElements() == true || \\\n+             (this->hasChildElements() == false && (static_cast<const CElementArray*>(this->getConstParentNode()))->anyElementsHaveMaxOccursGreaterThanOne() == false)/* || \\\n+             (this->isTopLevelElement() == true && (pAttributeGroupArray != NULL || pAttributeArray != NULL))*/))\n+\n+    {\n+        return true;\n+    }\n+    else\n+    {\n+        return false;\n+    }\n+/*    if (stricmp(this->getMaxOccurs(), TAG_UNBOUNDED) == 0)\n+    {\n+        return false;\n+    }\n+    // Any element that is in sequence of complex type will be a tab\n+    else*/ if (this->getConstAncestorNode(3)->getNodeType() == XSD_SEQUENCE && this->getConstAncestorNode(3)->getNodeType() == XSD_COMPLEX_TYPE)\n+    {\n+        return true;\n+    }\n+    else if (/*this->getConstAncestorNode(3)->getNodeType == XSD_COMPLEX_TYPE &&*/ this->getConstAncestorNode(3)->getNodeType() == XSD_ELEMENT)\n+    {\n+        const CElement *pElement = dynamic_cast<const CElement*>(this->getConstAncestorNode(3));\n+\n+        assert(pElement != NULL);\n+        if (pElement != NULL)\n+            return pElement->isATab();\n+    }\n+    return false;\n+}\n+\n+bool CElement::isLastTab(const int idx) const\n+{\n+    assert(this->isATab() == true);\n+\n+    const CElementArray *pElementArray = dynamic_cast<const CElementArray*>(this->getConstParentNode());\n+\n+    if (pElementArray == NULL)\n+    {\n+        assert(!\"Corrupt XSD??\");\n+        return false;\n+    }\n+    if (pElementArray->length()-1 == idx)\n+        return true;\n+\n+    return false;\n+}\n+\n+\n+void CElement::populateEnvXPath(::StringBuffer strXPath, unsigned int index)\n+{\n+    assert(strXPath.length() > 0);\n+\n+    //strXPath.append(\"/\").append(this->getName()).append(\"[\").append(index).append(\"]\");\n+    strXPath.append(\"[\").append(index).append(\"]\");\n+\n+    //PROGLOG(\"Setting element to envpath of %s, previous path: %s\", strXPath.str(), this->getEnvXPath());\n+    this->setEnvXPath(strXPath);\n+\n+    CConfigSchemaHelper::getInstance()->getSchemaMapManager()->addMapOfXPathToElement(this->getEnvXPath(), this);\n+\n+    if (m_pComplexTypeArray != NULL)\n+        m_pComplexTypeArray->populateEnvXPath(strXPath, index);\n+    if (m_pSimpleType != NULL)\n+        m_pSimpleType->populateEnvXPath(strXPath, index);\n+    if (m_pKeyArray != NULL)\n+        m_pKeyArray->populateEnvXPath(strXPath, index);\n+}\n+\n+void CElement::loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree)\n+{\n+    //PROGLOG(\"Mapping element with XPATH of %s to %p\", this->getEnvXPath(), this);\n+    //CConfigSchemaHelper::getInstance()->getSchemaMapManager()->addMapOfXPathToElement(this->getEnvXPath(), this);\n+\n+    if (m_pComplexTypeArray != NULL)\n+    {\n+        try\n+        {\n+            m_pComplexTypeArray->loadXMLFromEnvXml(pEnvTree);\n+        }\n+        catch (...)\n+        {\n+            // node described in XSD doesn't exist in XML\n+            // time to do validation?\n+        }\n+    }\n+    if (m_pSimpleType != NULL)\n+    {\n+        try\n+        {\n+            m_pSimpleType->loadXMLFromEnvXml(pEnvTree);\n+        }\n+        catch(...)\n+        {\n+        }\n+    }\n+\n+    if (m_pComplexTypeArray == NULL)\n+    {\n+        const char* pValue =  pEnvTree->queryPropTree(this->getEnvXPath())->queryProp(\"\");\n+\n+        if (pValue != NULL)\n+        {\n+            this->setEnvValueFromXML(pValue);\n+            CConfigSchemaHelper::getInstance()->appendElementXPath(this->getEnvXPath());\n+        }\n+    }\n+\n+    const char* pInstanceName =  pEnvTree->queryPropTree(this->getEnvXPath())->queryProp(XML_ATTR_NAME);\n+\n+    if (pInstanceName != NULL && *pInstanceName != 0)\n+        this->setInstanceName(pInstanceName);\n+}\n+\n+bool CElement::isTopLevelElement() const\n+{\n+    return m_bTopLevelElement;\n+}\n+\n+const char * CElement::getViewType() const\n+{\n+    if(m_pAnnotation != NULL && m_pAnnotation->getAppInfo() != NULL)\n+        return m_pAnnotation->getAppInfo()->getViewType();\n+    return NULL;\n+}\n+\n+void CElementArray::dump(::std::ostream &cout, unsigned int offset) const\n+{\n+    offset+= STANDARD_OFFSET_1;\n+\n+    QuickOutHeader(cout, XSD_ELEMENT_ARRAY_STR, offset);\n+    QUICK_OUT(cout, XSDXPath,  offset);\n+    QUICK_OUT(cout, EnvXPath,  offset);\n+    QUICK_OUT_ARRAY(cout, offset);\n+    QuickOutFooter(cout, XSD_ELEMENT_ARRAY_STR, offset);\n+}\n+\n+void CElementArray::getDocumentation(::StringBuffer &strDoc) const\n+{\n+    QUICK_DOC_ARRAY(strDoc);\n+}\n+\n+void CElementArray::getJSON(::StringBuffer &strJSON, unsigned int offset, int idx) const\n+{\n+    offset += STANDARD_OFFSET_2;\n+    QuickOutPad(strJSON, offset);\n+\n+    int lidx = (idx == -1 ? 0 : idx);\n+\n+    strJSON.append(\"{\");\n+\n+    (this->item(lidx)).getJSON(strJSON, offset+STANDARD_OFFSET_2, lidx);\n+\n+    offset += STANDARD_OFFSET_2;\n+    QuickOutPad(strJSON, offset);\n+    strJSON.append(\"}\");\n+}\n+\n+void CElementArray::populateEnvXPath(::StringBuffer strXPath, unsigned int index)\n+{\n+    strXPath.appendf(\"/%s\", this->item(0).getName());\n+    this->setEnvXPath(strXPath);\n+\n+    for (int idx=0; idx < this->length(); idx++)\n+    {\n+        //strXPath.appendf(\"[%d]\", idx+1);\n+        this->item(idx).populateEnvXPath(strXPath.str(), idx+1);\n+        CConfigSchemaHelper::stripXPathIndex(strXPath);\n+    }\n+}\n+\n+const char* CElementArray::getXML(const char* /*pComponent*/)\n+{\n+    if (m_strXML.length() == 0)\n+    {\n+        int length = this->length();\n+\n+        for (int idx = 0; idx < length; idx++)\n+        {\n+            CElement &Element = this->item(idx);\n+            m_strXML.append(Element.getXML(NULL));\n+\n+            if (idx+1 < length)\n+                m_strXML.append(\"\\n\");\n+        }\n+    }\n+    return m_strXML.str();\n+}\n+\n+void CElementArray::loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree)\n+{\n+    ::StringBuffer strEnvXPath(this->getEnvXPath());\n+    int subIndex = 1;\n+\n+    do\n+    {\n+        CElement *pElement = NULL;\n+\n+        strEnvXPath.appendf(\"[%d]\", subIndex);\n+        if (pEnvTree->hasProp(strEnvXPath.str()) == false)\n+             return;\n+\n+        if (subIndex == 1)\n+        {\n+            pElement =  CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getElementFromXPath(strEnvXPath.str());\n+        }\n+        else\n+        {\n+            pElement = CElement::load(this, this->getSchemaRoot(), this->getXSDXPath(), false);\n+            this->append(*pElement);\n+        }\n+\n+        assert(pElement);\n+\n+        if (subIndex > 1)\n+        {\n+            pElement->populateEnvXPath(this->getEnvXPath(), subIndex);\n+        }\n+\n+        pElement->setTopLevelElement(false);\n+        pElement->loadXMLFromEnvXml(pEnvTree);\n+\n+        CConfigSchemaHelper::stripXPathIndex(strEnvXPath);\n+\n+        subIndex++;\n+    } while (true);\n+}\n+\n+CElementArray* CElementArray::load(const char* pSchemaFile)\n+{\n+    assert(pSchemaFile != NULL);\n+    if (pSchemaFile == NULL)\n+        return NULL;\n+\n+    typedef ::IPropertyTree jlibIPropertyTree;\n+    ::Linked<jlibIPropertyTree> pSchemaRoot;\n+    ::StringBuffer schemaPath;\n+\n+    schemaPath.appendf(\"%s%s\", DEFAULT_SCHEMA_DIRECTORY, pSchemaFile);\n+    pSchemaRoot.setown(createPTreeFromXMLFile(schemaPath.str()));\n+\n+    CElementArray *pElemArray = CElementArray::load(NULL, pSchemaRoot, XSD_TAG_ELEMENT);\n+\n+    //PROGLOG(\"Function: %s() at %s:%d\", __func__, __FILE__, __LINE__);\n+    //PROGLOG(\"pElemArray = %p\", pElemArray);\n+\n+    return pElemArray;\n+}\n+\n+CElementArray* CElementArray::load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath)\n+{\n+    assert(pSchemaRoot != NULL);\n+    if (pSchemaRoot == NULL)\n+        return NULL;\n+\n+    CElementArray *pElemArray = new CElementArray(pParentNode);\n+    assert(pElemArray != NULL);\n+\n+    pSchemaRoot->Link();\n+    pElemArray->setSchemaRoot(pSchemaRoot);\n+\n+    ::StringBuffer strXPathExt(xpath);\n+    pElemArray->setXSDXPath(xpath);\n+\n+    CElement *pElem = CElement::load(pElemArray, pSchemaRoot, strXPathExt.str());\n+\n+    assert(pElem);\n+    pElemArray->append(*pElem);\n+\n+    SETPARENTNODE(pElemArray, pParentNode);\n+\n+    return pElemArray;\n+\n+\n+/*    typedef ::IPropertyTreeIterator jlibIPropertyTreeIterator;\n+    Owned<jlibIPropertyTreeIterator> elemIter = pSchemaRoot->getElements(xpath);\n+\n+    CElement *pElem = CElement::load(pElemArray, pSchemaRoot, strXPathExt.str());\n+\n+    assert(pElem);\n+    pElemArray->append(*pElem);\n+\n+    SETPARENTNODE(pElemArray, pParentNode);\n+\n+    return pElemArray;\n+\n+    int count = 1;\n+\n+    ForEach(*elemIter)\n+    {\n+        strXPathExt.set(xpath);\n+        strXPathExt.appendf(\"[%d]\", count);\n+\n+        CElement *pElem = CElement::load(pElemArray, pSchemaRoot, strXPathExt.str());\n+\n+        assert(pElem);\n+        pElemArray->append(*pElem);\n+\n+        count++;\n+    }\n+\n+    if (pElemArray->length() == 0)\n+    {\n+        delete pElemArray;\n+        return NULL;\n+    }\n+\n+    SETPARENTNODE(pElemArray, pParentNode);\n+\n+    return pElemArray;*/\n+}\n+\n+int CElementArray::getCountOfSiblingElements(const char *pXPath) const\n+{\n+    assert(pXPath != NULL && *pXPath != 0);\n+\n+    int count = 0;\n+\n+    for (int idx=0; idx < this->length(); idx++)\n+    {\n+        if (strcmp(this->item(idx).getXSDXPath(), pXPath) == 0)\n+            count++;\n+    }\n+    return count;\n+}\n+\n+const CXSDNodeBase* CElementArray::getNodeByTypeAndNameAscending(NODE_TYPES eNodeType, const char *pName) const\n+{\n+    assert(pName != NULL);\n+\n+    for (int idx = 1; idx < this->length() && eNodeType == XSD_ELEMENT; idx++)\n+    {\n+        if (strcmp ((static_cast<CElement>(this->item(idx))).getName(), pName) == 0)\n+            return &(this->item(idx));\n+    }\n+    return (this->getParentNode()->getNodeByTypeAndNameAscending(eNodeType, pName));","path":"configuration/configurator/SchemaElement.cpp","position":718,"original_position":718,"commit_id":"001775c9bf2f93b607da0518fe713de7bcd9ce83","original_commit_id":"001775c9bf2f93b607da0518fe713de7bcd9ce83","user":{"login":"wangkx","id":903406,"avatar_url":"https://avatars.githubusercontent.com/u/903406?v=3","gravatar_id":"","url":"https://api.github.com/users/wangkx","html_url":"https://github.com/wangkx","followers_url":"https://api.github.com/users/wangkx/followers","following_url":"https://api.github.com/users/wangkx/following{/other_user}","gists_url":"https://api.github.com/users/wangkx/gists{/gist_id}","starred_url":"https://api.github.com/users/wangkx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wangkx/subscriptions","organizations_url":"https://api.github.com/users/wangkx/orgs","repos_url":"https://api.github.com/users/wangkx/repos","events_url":"https://api.github.com/users/wangkx/events{/privacy}","received_events_url":"https://api.github.com/users/wangkx/received_events","type":"User","site_admin":false},"body":"Is it possible that this->getParentNode() returns NULL?","created_at":"2016-08-03T18:43:37Z","updated_at":"2016-08-03T18:43:37Z","html_url":"https://github.com/hpcc-systems/HPCC-Platform/pull/8958#discussion_r73395855","pull_request_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/8958","_links":{"self":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/comments/73395855"},"html":{"href":"https://github.com/hpcc-systems/HPCC-Platform/pull/8958#discussion_r73395855"},"pull_request":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/8958"}}},"pull_request":{"url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/8958","id":79634293,"html_url":"https://github.com/hpcc-systems/HPCC-Platform/pull/8958","diff_url":"https://github.com/hpcc-systems/HPCC-Platform/pull/8958.diff","patch_url":"https://github.com/hpcc-systems/HPCC-Platform/pull/8958.patch","issue_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/issues/8958","number":8958,"state":"open","locked":false,"title":"ConfigMgr 2.0 - The Configurator","user":{"login":"garonsky","id":1322284,"avatar_url":"https://avatars.githubusercontent.com/u/1322284?v=3","gravatar_id":"","url":"https://api.github.com/users/garonsky","html_url":"https://github.com/garonsky","followers_url":"https://api.github.com/users/garonsky/followers","following_url":"https://api.github.com/users/garonsky/following{/other_user}","gists_url":"https://api.github.com/users/garonsky/gists{/gist_id}","starred_url":"https://api.github.com/users/garonsky/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/garonsky/subscriptions","organizations_url":"https://api.github.com/users/garonsky/orgs","repos_url":"https://api.github.com/users/garonsky/repos","events_url":"https://api.github.com/users/garonsky/events{/privacy}","received_events_url":"https://api.github.com/users/garonsky/received_events","type":"User","site_admin":false},"body":"- Prototype \r\n\r\nSigned-off-by: Gleb Aronsky <gleb.aronsky@lexisnexis.com>","created_at":"2016-08-01T20:51:22Z","updated_at":"2016-08-03T18:43:37Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a58be9679dc68ac5fc6f840c6de673d51a5fa30f","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/8958/commits","review_comments_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/8958/comments","review_comment_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/comments{/number}","comments_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/issues/8958/comments","statuses_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/statuses/001775c9bf2f93b607da0518fe713de7bcd9ce83","head":{"label":"garonsky:integrate_configurator_for_merge","ref":"integrate_configurator_for_merge","sha":"001775c9bf2f93b607da0518fe713de7bcd9ce83","user":{"login":"garonsky","id":1322284,"avatar_url":"https://avatars.githubusercontent.com/u/1322284?v=3","gravatar_id":"","url":"https://api.github.com/users/garonsky","html_url":"https://github.com/garonsky","followers_url":"https://api.github.com/users/garonsky/followers","following_url":"https://api.github.com/users/garonsky/following{/other_user}","gists_url":"https://api.github.com/users/garonsky/gists{/gist_id}","starred_url":"https://api.github.com/users/garonsky/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/garonsky/subscriptions","organizations_url":"https://api.github.com/users/garonsky/orgs","repos_url":"https://api.github.com/users/garonsky/repos","events_url":"https://api.github.com/users/garonsky/events{/privacy}","received_events_url":"https://api.github.com/users/garonsky/received_events","type":"User","site_admin":false},"repo":{"id":3462822,"name":"HPCC-Platform","full_name":"garonsky/HPCC-Platform","owner":{"login":"garonsky","id":1322284,"avatar_url":"https://avatars.githubusercontent.com/u/1322284?v=3","gravatar_id":"","url":"https://api.github.com/users/garonsky","html_url":"https://github.com/garonsky","followers_url":"https://api.github.com/users/garonsky/followers","following_url":"https://api.github.com/users/garonsky/following{/other_user}","gists_url":"https://api.github.com/users/garonsky/gists{/gist_id}","starred_url":"https://api.github.com/users/garonsky/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/garonsky/subscriptions","organizations_url":"https://api.github.com/users/garonsky/orgs","repos_url":"https://api.github.com/users/garonsky/repos","events_url":"https://api.github.com/users/garonsky/events{/privacy}","received_events_url":"https://api.github.com/users/garonsky/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/garonsky/HPCC-Platform","description":"HPCC Systems big data solution, community edition","fork":true,"url":"https://api.github.com/repos/garonsky/HPCC-Platform","forks_url":"https://api.github.com/repos/garonsky/HPCC-Platform/forks","keys_url":"https://api.github.com/repos/garonsky/HPCC-Platform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/garonsky/HPCC-Platform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/garonsky/HPCC-Platform/teams","hooks_url":"https://api.github.com/repos/garonsky/HPCC-Platform/hooks","issue_events_url":"https://api.github.com/repos/garonsky/HPCC-Platform/issues/events{/number}","events_url":"https://api.github.com/repos/garonsky/HPCC-Platform/events","assignees_url":"https://api.github.com/repos/garonsky/HPCC-Platform/assignees{/user}","branches_url":"https://api.github.com/repos/garonsky/HPCC-Platform/branches{/branch}","tags_url":"https://api.github.com/repos/garonsky/HPCC-Platform/tags","blobs_url":"https://api.github.com/repos/garonsky/HPCC-Platform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/garonsky/HPCC-Platform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/garonsky/HPCC-Platform/git/refs{/sha}","trees_url":"https://api.github.com/repos/garonsky/HPCC-Platform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/garonsky/HPCC-Platform/statuses/{sha}","languages_url":"https://api.github.com/repos/garonsky/HPCC-Platform/languages","stargazers_url":"https://api.github.com/repos/garonsky/HPCC-Platform/stargazers","contributors_url":"https://api.github.com/repos/garonsky/HPCC-Platform/contributors","subscribers_url":"https://api.github.com/repos/garonsky/HPCC-Platform/subscribers","subscription_url":"https://api.github.com/repos/garonsky/HPCC-Platform/subscription","commits_url":"https://api.github.com/repos/garonsky/HPCC-Platform/commits{/sha}","git_commits_url":"https://api.github.com/repos/garonsky/HPCC-Platform/git/commits{/sha}","comments_url":"https://api.github.com/repos/garonsky/HPCC-Platform/comments{/number}","issue_comment_url":"https://api.github.com/repos/garonsky/HPCC-Platform/issues/comments{/number}","contents_url":"https://api.github.com/repos/garonsky/HPCC-Platform/contents/{+path}","compare_url":"https://api.github.com/repos/garonsky/HPCC-Platform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/garonsky/HPCC-Platform/merges","archive_url":"https://api.github.com/repos/garonsky/HPCC-Platform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/garonsky/HPCC-Platform/downloads","issues_url":"https://api.github.com/repos/garonsky/HPCC-Platform/issues{/number}","pulls_url":"https://api.github.com/repos/garonsky/HPCC-Platform/pulls{/number}","milestones_url":"https://api.github.com/repos/garonsky/HPCC-Platform/milestones{/number}","notifications_url":"https://api.github.com/repos/garonsky/HPCC-Platform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/garonsky/HPCC-Platform/labels{/name}","releases_url":"https://api.github.com/repos/garonsky/HPCC-Platform/releases{/id}","deployments_url":"https://api.github.com/repos/garonsky/HPCC-Platform/deployments","created_at":"2012-02-16T18:57:52Z","updated_at":"2016-06-10T18:31:28Z","pushed_at":"2016-08-01T21:21:37Z","git_url":"git://github.com/garonsky/HPCC-Platform.git","ssh_url":"git@github.com:garonsky/HPCC-Platform.git","clone_url":"https://github.com/garonsky/HPCC-Platform.git","svn_url":"https://github.com/garonsky/HPCC-Platform","homepage":"hpccsystems.com","size":151421,"stargazers_count":1,"watchers_count":1,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"hpcc-systems:master","ref":"master","sha":"79d812c5fe0063f64768d2502f9b470219e791dd","user":{"login":"hpcc-systems","id":900867,"avatar_url":"https://avatars.githubusercontent.com/u/900867?v=3","gravatar_id":"","url":"https://api.github.com/users/hpcc-systems","html_url":"https://github.com/hpcc-systems","followers_url":"https://api.github.com/users/hpcc-systems/followers","following_url":"https://api.github.com/users/hpcc-systems/following{/other_user}","gists_url":"https://api.github.com/users/hpcc-systems/gists{/gist_id}","starred_url":"https://api.github.com/users/hpcc-systems/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hpcc-systems/subscriptions","organizations_url":"https://api.github.com/users/hpcc-systems/orgs","repos_url":"https://api.github.com/users/hpcc-systems/repos","events_url":"https://api.github.com/users/hpcc-systems/events{/privacy}","received_events_url":"https://api.github.com/users/hpcc-systems/received_events","type":"Organization","site_admin":false},"repo":{"id":2030681,"name":"HPCC-Platform","full_name":"hpcc-systems/HPCC-Platform","owner":{"login":"hpcc-systems","id":900867,"avatar_url":"https://avatars.githubusercontent.com/u/900867?v=3","gravatar_id":"","url":"https://api.github.com/users/hpcc-systems","html_url":"https://github.com/hpcc-systems","followers_url":"https://api.github.com/users/hpcc-systems/followers","following_url":"https://api.github.com/users/hpcc-systems/following{/other_user}","gists_url":"https://api.github.com/users/hpcc-systems/gists{/gist_id}","starred_url":"https://api.github.com/users/hpcc-systems/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hpcc-systems/subscriptions","organizations_url":"https://api.github.com/users/hpcc-systems/orgs","repos_url":"https://api.github.com/users/hpcc-systems/repos","events_url":"https://api.github.com/users/hpcc-systems/events{/privacy}","received_events_url":"https://api.github.com/users/hpcc-systems/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/hpcc-systems/HPCC-Platform","description":"HPCC Systems (High Performance Computing Cluster) is an open source, massive parallel-processing computing platform for big data processing and analytics.","fork":false,"url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform","forks_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/forks","keys_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/teams","hooks_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/hooks","issue_events_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/issues/events{/number}","events_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/events","assignees_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/assignees{/user}","branches_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/branches{/branch}","tags_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/tags","blobs_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/git/refs{/sha}","trees_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/statuses/{sha}","languages_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/languages","stargazers_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/stargazers","contributors_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/contributors","subscribers_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/subscribers","subscription_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/subscription","commits_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/commits{/sha}","git_commits_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/git/commits{/sha}","comments_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/comments{/number}","issue_comment_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/issues/comments{/number}","contents_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/contents/{+path}","compare_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/merges","archive_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/downloads","issues_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/issues{/number}","pulls_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls{/number}","milestones_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/milestones{/number}","notifications_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/labels{/name}","releases_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/releases{/id}","deployments_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/deployments","created_at":"2011-07-11T14:29:51Z","updated_at":"2016-07-19T08:28:43Z","pushed_at":"2016-08-03T18:24:11Z","git_url":"git://github.com/hpcc-systems/HPCC-Platform.git","ssh_url":"git@github.com:hpcc-systems/HPCC-Platform.git","clone_url":"https://github.com/hpcc-systems/HPCC-Platform.git","svn_url":"https://github.com/hpcc-systems/HPCC-Platform","homepage":"http://hpccsystems.com","size":180139,"stargazers_count":284,"watchers_count":284,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":150,"mirror_url":null,"open_issues_count":438,"forks":150,"open_issues":438,"watchers":284,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/8958"},"html":{"href":"https://github.com/hpcc-systems/HPCC-Platform/pull/8958"},"issue":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/issues/8958"},"comments":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/issues/8958/comments"},"review_comments":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/8958/comments"},"review_comment":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/8958/commits"},"statuses":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/statuses/001775c9bf2f93b607da0518fe713de7bcd9ce83"}}}}
{"actor":{"display_login":"wangkx"}}