Explorar o código

ConfigMgr 2.0 - The Configurator

- Prototype

Signed-off-by: Gleb Aronsky <gleb.aronsky@lexisnexis.com>
Gleb Aronsky %!s(int64=9) %!d(string=hai) anos
pai
achega
c8b73e1a8d
Modificáronse 100 ficheiros con 14024 adicións e 0 borrados
  1. 5 0
      CMakeLists.txt
  2. 96 0
      cmake_modules/commonSetup.cmake
  3. 17 0
      configuration/CMakeLists.txt
  4. 246 0
      configuration/configurator/BuildSet.cpp
  5. 122 0
      configuration/configurator/BuildSet.hpp
  6. 40 0
      configuration/configurator/CMakeLists.txt
  7. 56 0
      configuration/configurator/ConfigFileComponentUtils.cpp
  8. 49 0
      configuration/configurator/ConfigFileComponentUtils.hpp
  9. 158 0
      configuration/configurator/ConfigFileUtils.cpp
  10. 73 0
      configuration/configurator/ConfigFileUtils.hpp
  11. 50 0
      configuration/configurator/ConfigFileUtilsObservable.cpp
  12. 60 0
      configuration/configurator/ConfigFileUtilsObservable.hpp
  13. 26 0
      configuration/configurator/ConfigFileUtilsObserver.ipp
  14. 106 0
      configuration/configurator/ConfigNotifications.cpp
  15. 103 0
      configuration/configurator/ConfigNotifications.hpp
  16. 898 0
      configuration/configurator/ConfigSchemaHelper.cpp
  17. 192 0
      configuration/configurator/ConfigSchemaHelper.hpp
  18. 558 0
      configuration/configurator/ConfiguratorAPI.cpp
  19. 80 0
      configuration/configurator/ConfiguratorAPI.hpp
  20. 352 0
      configuration/configurator/ConfiguratorMain.cpp
  21. 26 0
      configuration/configurator/ConfiguratorMain.hpp
  22. 52 0
      configuration/configurator/DocumentationMarkup.hpp
  23. 80 0
      configuration/configurator/EnvironmentConfiguration.cpp
  24. 55 0
      configuration/configurator/EnvironmentConfiguration.hpp
  25. 239 0
      configuration/configurator/EnvironmentModel.cpp
  26. 78 0
      configuration/configurator/EnvironmentModel.hpp
  27. 39 0
      configuration/configurator/ExceptionStrings.cpp
  28. 104 0
      configuration/configurator/ExceptionStrings.hpp
  29. 159 0
      configuration/configurator/JSONMarkUp.cpp
  30. 77 0
      configuration/configurator/JSONMarkUp.hpp
  31. 50 0
      configuration/configurator/SchemaAll.hpp
  32. 86 0
      configuration/configurator/SchemaAnnotation.cpp
  33. 69 0
      configuration/configurator/SchemaAnnotation.hpp
  34. 131 0
      configuration/configurator/SchemaAppInfo.cpp
  35. 77 0
      configuration/configurator/SchemaAppInfo.hpp
  36. 357 0
      configuration/configurator/SchemaAttributeGroup.cpp
  37. 119 0
      configuration/configurator/SchemaAttributeGroup.hpp
  38. 594 0
      configuration/configurator/SchemaAttributes.cpp
  39. 148 0
      configuration/configurator/SchemaAttributes.hpp
  40. 134 0
      configuration/configurator/SchemaChoice.cpp
  41. 66 0
      configuration/configurator/SchemaChoice.hpp
  42. 434 0
      configuration/configurator/SchemaCommon.cpp
  43. 682 0
      configuration/configurator/SchemaCommon.hpp
  44. 82 0
      configuration/configurator/SchemaComplexContent.cpp
  45. 58 0
      configuration/configurator/SchemaComplexContent.hpp
  46. 443 0
      configuration/configurator/SchemaComplexType.cpp
  47. 131 0
      configuration/configurator/SchemaComplexType.hpp
  48. 56 0
      configuration/configurator/SchemaDocumentation.cpp
  49. 62 0
      configuration/configurator/SchemaDocumentation.hpp
  50. 887 0
      configuration/configurator/SchemaElement.cpp
  51. 266 0
      configuration/configurator/SchemaElement.hpp
  52. 198 0
      configuration/configurator/SchemaEnumeration.cpp
  53. 98 0
      configuration/configurator/SchemaEnumeration.hpp
  54. 97 0
      configuration/configurator/SchemaExtension.cpp
  55. 62 0
      configuration/configurator/SchemaExtension.hpp
  56. 137 0
      configuration/configurator/SchemaField.cpp
  57. 110 0
      configuration/configurator/SchemaField.hpp
  58. 74 0
      configuration/configurator/SchemaFractionDigits.cpp
  59. 60 0
      configuration/configurator/SchemaFractionDigits.hpp
  60. 152 0
      configuration/configurator/SchemaInclude.cpp
  61. 104 0
      configuration/configurator/SchemaInclude.hpp
  62. 222 0
      configuration/configurator/SchemaKey.cpp
  63. 102 0
      configuration/configurator/SchemaKey.hpp
  64. 178 0
      configuration/configurator/SchemaKeyRef.cpp
  65. 91 0
      configuration/configurator/SchemaKeyRef.hpp
  66. 67 0
      configuration/configurator/SchemaLength.cpp
  67. 59 0
      configuration/configurator/SchemaLength.hpp
  68. 593 0
      configuration/configurator/SchemaMapManager.cpp
  69. 152 0
      configuration/configurator/SchemaMapManager.hpp
  70. 30 0
      configuration/configurator/SchemaMaxExclusive.cpp
  71. 46 0
      configuration/configurator/SchemaMaxExclusive.hpp
  72. 30 0
      configuration/configurator/SchemaMaxInclusive.cpp
  73. 46 0
      configuration/configurator/SchemaMaxInclusive.hpp
  74. 30 0
      configuration/configurator/SchemaMaxLength.cpp
  75. 46 0
      configuration/configurator/SchemaMaxLength.hpp
  76. 31 0
      configuration/configurator/SchemaMinExclusive.cpp
  77. 45 0
      configuration/configurator/SchemaMinExclusive.hpp
  78. 30 0
      configuration/configurator/SchemaMinInclusive.cpp
  79. 46 0
      configuration/configurator/SchemaMinInclusive.hpp
  80. 30 0
      configuration/configurator/SchemaMinLength.cpp
  81. 45 0
      configuration/configurator/SchemaMinLength.hpp
  82. 30 0
      configuration/configurator/SchemaPattern.cpp
  83. 46 0
      configuration/configurator/SchemaPattern.hpp
  84. 176 0
      configuration/configurator/SchemaRestriction.cpp
  85. 88 0
      configuration/configurator/SchemaRestriction.hpp
  86. 364 0
      configuration/configurator/SchemaSchema.cpp
  87. 91 0
      configuration/configurator/SchemaSchema.hpp
  88. 94 0
      configuration/configurator/SchemaSelector.cpp
  89. 56 0
      configuration/configurator/SchemaSelector.hpp
  90. 119 0
      configuration/configurator/SchemaSequence.cpp
  91. 56 0
      configuration/configurator/SchemaSequence.hpp
  92. 81 0
      configuration/configurator/SchemaSimpleContent.cpp
  93. 90 0
      configuration/configurator/SchemaSimpleContent.hpp
  94. 198 0
      configuration/configurator/SchemaSimpleType.cpp
  95. 113 0
      configuration/configurator/SchemaSimpleType.hpp
  96. 31 0
      configuration/configurator/SchemaTotalDigits.cpp
  97. 46 0
      configuration/configurator/SchemaTotalDigits.hpp
  98. 113 0
      configuration/configurator/SchemaUnique.cpp
  99. 93 0
      configuration/configurator/SchemaUnique.hpp
  100. 0 0
      configuration/configurator/SchemaWhiteSpace.cpp

+ 5 - 0
CMakeLists.txt

@@ -466,6 +466,11 @@ if(TOP_LEVEL_PROJECT)
     endif(PLATFORM OR PLUGIN)
 endif(TOP_LEVEL_PROJECT)
 
+if (MAKE_CONFIGURATOR)
+    MESSAGE( "Configurator app build ON" )
+    HPCC_ADD_SUBDIRECTORY (configuration)
+endif()
+
 ###
 ## Below are the non-compile based install scripts required for
 ## the hpcc platform.

+ 96 - 0
cmake_modules/commonSetup.cmake

@@ -182,6 +182,102 @@ IF ("${COMMONSETUP_DONE}" STREQUAL "")
       endif()
   endif()
 
+  option(MAKE_CONFIGURATOR "Build Configurator" ON)
+  option(CONFIGURATOR_LIB "Build Configurator static library (.a)" OFF)
+
+  if ( CONFIGURATOR_LIB )
+        set( MAKE_CONFIGURATOR ON )
+  endif()
+
+  if (APPLE OR WIN32)
+      option(USE_TBB "Enable Threading Building Block support" OFF)
+  else()
+      option(USE_TBB "Enable Threading Building Block support" ON)
+      option(USE_TBBMALLOC "Enable Threading Building Block scalable allocator proxy support" ON)
+  endif()
+
+  option(LOGGING_SERVICE "Configure use of logging service" ON)
+
+
+    if(REMBED)
+	if(DEFINED pluginname)
+            message(FATAL_ERROR "Cannot enable rembed, already declared ${pluginname}")
+	    else()
+            set(pluginname "rembed")
+        endif()
+    endif()
+    if(V8EMBED)
+	    if(DEFINED pluginname)
+	        message(FATAL_ERROR "Cannot enable v8embed, already declared ${pluginname}")
+        else()
+            set(pluginname "v8embed")
+        endif()
+    endif()
+    if(MEMCACHED)
+	    if(DEFINED pluginname)
+	        message(FATAL_ERROR "Cannot enable memcached, already declared ${pluginname}")
+        else()
+            set(pluginname "memcached")
+        endif()
+    endif()
+    if(PYEMBED)
+	    if(DEFINED pluginname)
+	        message(FATAL_ERROR "Cannot enable pyembed, already declared ${pluginname}")
+        else()
+            set(pluginname "pyembed")
+        endif()
+    endif()
+    if(REDIS)
+	    if(DEFINED pluginname)
+	        message(FATAL_ERROR "Cannot enable redis, already declared ${pluginname}")
+        else()
+            set(pluginname "redis")
+        endif()
+    endif()
+    if(JAVAEMBED)
+	    if(DEFINED pluginname)
+	        message(FATAL_ERROR "Cannot enable javaembed, already declared ${pluginname}")
+        else()
+            set(pluginname "javaembed")
+        endif()
+    endif()
+    if(MYSQLEMBED)
+	    if(DEFINED pluginname)
+	        message(FATAL_ERROR "Cannot enable mysqlembed, already declared ${pluginname}")
+        else()
+            set(pluginname "mysqlembed")
+        endif()
+    endif()
+    if(SQLITE3EMBED)
+	    if(DEFINED pluginname)
+	         message(FATAL_ERROR "Cannot enable sqlite3embed, already declared ${pluginname}")
+        else()
+            set(pluginname "sqlite3embed")
+        endif()
+    endif()
+    if(KAFKA)
+	    if(DEFINED pluginname)
+	        message(FATAL_ERROR "Cannot enable kafka, already declared ${pluginname}")
+        else()
+            set(pluginname "kafka")
+        endif()
+    endif()
+    if(EXAMPLEPLUGIN)
+        if(DEFINED pluginname)
+            message(FATAL_ERROR "Cannot enable exampleplugin, already declared ${pluginname}")
+        else()
+           set(pluginname "exampleplugin")
+        endif()
+    endif()
+    if(COUCHBASEEMBED)
+        if(DEFINED pluginname)
+            message(FATAL_ERROR "Cannot enable couchbaseembed, already declared ${pluginname}")
+        else()
+            set(pluginname "couchbaseembed")
+        endif()
+    endif()
+
+>>>>>>> ConfigMgr 2.0 - The Configurator
   if ( USE_XALAN AND USE_LIBXSLT )
       set(USE_LIBXSLT OFF)
   endif()

+ 17 - 0
configuration/CMakeLists.txt

@@ -0,0 +1,17 @@
+################################################################################
+#    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+################################################################################
+
+HPCC_ADD_SUBDIRECTORY (configurator)

+ 246 - 0
configuration/configurator/BuildSet.cpp

@@ -0,0 +1,246 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jptree.hpp"
+#include "XMLTags.h"
+#include "BuildSet.hpp"
+#include "SchemaCommon.hpp"
+
+using namespace CONFIGURATOR;
+
+#define LOOP_THRU_BUILD_SET for (int idx = 0; idx < m_buildSetArray.length(); idx++)
+
+static CBuildSetManager *s_pBuildSetManager = NULL;
+
+CBuildSetManager* CBuildSetManager::getInstance(const char* pBuildSetFile, const char* pBuildSetDirectory)
+{
+    if (s_pBuildSetManager == NULL)
+    {
+        s_pBuildSetManager = new CBuildSetManager();
+
+        if (pBuildSetFile != NULL)
+            s_pBuildSetManager->m_buildSetFile.set(pBuildSetFile);
+        else
+            s_pBuildSetManager->m_buildSetFile.set(DEFAULT_BUILD_SET_XML_FILE);
+
+        if (pBuildSetDirectory != NULL)
+            s_pBuildSetManager->m_buildSetDir.set(pBuildSetDirectory);
+        else
+            s_pBuildSetManager->m_buildSetDir.set(DEFAULT_BUILD_SET_DIRECTORY);
+
+        pBuildSetFile = s_pBuildSetManager->m_buildSetFile;
+        pBuildSetDirectory = s_pBuildSetManager->m_buildSetDir;
+
+        s_pBuildSetManager->m_buildSetPath.clear().appendf("%s%s%s", pBuildSetDirectory, pBuildSetDirectory[strlen(pBuildSetDirectory)-1] == '/' ? "" : "/", pBuildSetFile);
+        s_pBuildSetManager->populateBuildSet();
+    }
+    return s_pBuildSetManager;
+}
+
+CBuildSetManager::CBuildSetManager(const char* pBuildSetFile, const char* pBuildSetDir) : m_buildSetFile(pBuildSetFile), m_buildSetDir(pBuildSetDir)
+{
+    if (pBuildSetFile != NULL && pBuildSetDir != NULL)
+       m_buildSetPath.clear().appendf("%s%s%s", pBuildSetDir, pBuildSetDir[strlen(pBuildSetDir)-1] == '/' ? "" : "/", pBuildSetFile);
+}
+
+CBuildSetManager::CBuildSetManager()
+{
+}
+
+CBuildSetManager::~CBuildSetManager()
+{
+    m_buildSetArray.kill();
+}
+
+void CBuildSetManager::getBuildSetComponents(StringArray& buildSetArray) const
+{
+    int nLength = this->getBuildSetComponentCount();
+
+    for (int idx = 0; idx < nLength; idx++)
+    {
+        buildSetArray.append(this->getBuildSetComponentTypeName(idx));
+    }
+}
+
+void CBuildSetManager::getBuildSetServices(StringArray& buildSetArray) const
+{
+    int nLength = this->getBuildSetServiceCount();
+
+    for (int idx = 0; idx < nLength; idx++)
+    {
+        buildSetArray.append(this->getBuildSetServiceName(idx));
+    }
+}
+
+const char* CBuildSetManager::getBuildSetServiceName(int index) const
+{
+    return this->getBuildSetService(index)->getName();
+}
+
+const char* CBuildSetManager::getBuildSetServiceFileName(int index) const
+{
+    return this->getBuildSetService(index)->getSchema();
+}
+
+const char* CBuildSetManager::getBuildSetComponentTypeName(int index) const
+{
+    return this->getBuildSetComponent(index)->getName();
+}
+
+const char* CBuildSetManager::getBuildSetComponentFileName(int index) const
+{
+    return this->getBuildSetComponent(index)->getSchema();
+}
+
+const char* CBuildSetManager::getBuildSetProcessName(int index) const
+{
+    return this->getBuildSetComponent(index)->getProcessName();
+}
+
+bool CBuildSetManager::populateBuildSet()
+{
+    StringBuffer xpath;
+
+    if (m_buildSetTree.get() != NULL)
+        return false;
+
+    try
+    {
+        m_buildSetTree.set(createPTreeFromXMLFile(m_buildSetPath.str()));
+    }
+    catch(...)
+    {
+        return false;
+    }
+
+    xpath.appendf("./%s/%s/%s", XML_TAG_PROGRAMS, XML_TAG_BUILD, XML_TAG_BUILDSET);
+
+    Owned<IPropertyTreeIterator> iter = m_buildSetTree->getElements(xpath.str());
+
+    ForEach(*iter)
+    {
+        IPropertyTree* pTree = &iter->query();
+
+        if ( pTree->queryProp(XML_ATTR_PROCESS_NAME) == NULL || pTree->queryProp(XML_ATTR_OVERIDE) != NULL || ( (pTree->queryProp(XML_ATTR_DEPLOYABLE) != NULL && \
+                stricmp(pTree->queryProp(XML_ATTR_DEPLOYABLE), "no") == 0 && stricmp(pTree->queryProp(XML_ATTR_PROCESS_NAME), XML_TAG_ESPSERVICE) != 0) ) )
+            continue;
+
+        Owned<CBuildSet> pBuildSet = new CBuildSet(pTree->queryProp(XML_ATTR_INSTALLSET), pTree->queryProp(XML_ATTR_NAME), pTree->queryProp(XML_ATTR_PROCESS_NAME),\
+                                                   pTree->queryProp(XML_ATTR_SCHEMA), pTree->queryProp(XML_ATTR_DEPLOYABLE), pTree->queryProp(XML_ATTR_OVERIDE));
+
+        m_buildSetArray.append(*pBuildSet.getLink());
+    }
+    return true;
+}
+
+void CBuildSetManager::setBuildSetArray(const StringArray &strArray)
+{
+    m_buildSetArray.kill();
+
+    for (int idx = 0; idx < strArray.length(); idx++)
+    {
+        Owned<CBuildSet> pBSet = new CBuildSet(NULL, strArray.item(idx), NULL, strArray.item(idx));
+        assert (pBSet != NULL);
+        m_buildSetArray.append(*pBSet.getClear());
+    }
+}
+
+const char* CBuildSetManager::getBuildSetSchema(int index) const
+{
+    assert(index < m_buildSetArray.length());
+    if (index < m_buildSetArray.length())
+        return m_buildSetArray.item(index).getSchema();
+    else
+        return NULL;
+}
+
+const int CBuildSetManager::getBuildSetSchemaCount() const
+{
+    return m_buildSetArray.length();
+}
+
+const int CBuildSetManager::getBuildSetServiceCount() const
+{
+    int nCount = 0;
+
+    LOOP_THRU_BUILD_SET
+    {
+        if (m_buildSetArray.item(idx).getProcessName() != NULL && strcmp(m_buildSetArray.item(idx).getProcessName(), XML_TAG_ESPSERVICE) == 0 && \
+                (m_buildSetArray.item(idx).getDeployable() != NULL && stricmp(m_buildSetArray.item(idx).getDeployable(), "no") == 0))
+            nCount++;
+    }
+    return nCount;
+}
+
+const int CBuildSetManager::getBuildSetComponentCount() const
+{
+    int nCount = 0;
+
+    LOOP_THRU_BUILD_SET
+    {
+        if ( ((m_buildSetArray.item(idx).getProcessName() == NULL) || (strcmp(m_buildSetArray.item(idx).getProcessName(), XML_TAG_ESPSERVICE) != 0)) && \
+                ( (m_buildSetArray.item(idx).getDeployable() == NULL) || (stricmp(m_buildSetArray.item(idx).getDeployable(), "no") != 0) ) && \
+                ( (m_buildSetArray.item(idx).getOveride() == NULL) || (stricmp(m_buildSetArray.item(idx).getOveride(), "no")    != 0) ) )
+            nCount++;
+    }
+    return nCount;
+}
+
+const CBuildSet* CBuildSetManager::getBuildSetComponent(int index) const
+{
+    int nCount = 0;
+
+    LOOP_THRU_BUILD_SET
+    {
+        if (index == 0)
+        {
+            if ( ((m_buildSetArray.item(idx).getProcessName() == NULL) || (strcmp(m_buildSetArray.item(idx).getProcessName(), XML_TAG_ESPSERVICE) != 0)) && \
+                    ( (m_buildSetArray.item(idx).getDeployable() == NULL) || (stricmp(m_buildSetArray.item(idx).getDeployable(), "no") != 0) ) && \
+                    ( (m_buildSetArray.item(idx).getOveride() == NULL) || (stricmp(m_buildSetArray.item(idx).getOveride(), "no") != 0) ) )
+                return &(m_buildSetArray.item(idx));
+            else
+                continue;
+        }
+        if ( ((m_buildSetArray.item(idx).getProcessName() == NULL) || (strcmp(m_buildSetArray.item(idx).getProcessName(), XML_TAG_ESPSERVICE) != 0)) && \
+                ( (m_buildSetArray.item(idx).getDeployable() == NULL)|| (stricmp(m_buildSetArray.item(idx).getDeployable(), "no") != 0) ) && \
+                ( (m_buildSetArray.item(idx).getOveride() == NULL) || (stricmp(m_buildSetArray.item(idx).getOveride(), "no") != 0) ) )
+            index--;
+    }
+    assert(!"index invalid");
+    return NULL;
+}
+
+const CBuildSet* CBuildSetManager::getBuildSetService(int index) const
+{
+    LOOP_THRU_BUILD_SET
+    {
+        if (index == 0)
+        {
+            if (m_buildSetArray.item(idx).getProcessName() != NULL && strcmp(m_buildSetArray.item(idx).getProcessName(), XML_TAG_ESPSERVICE) == 0 && \
+                    (m_buildSetArray.item(idx).getDeployable() != NULL && stricmp(m_buildSetArray.item(idx).getDeployable(), "no") == 0))
+                return &(m_buildSetArray.item(idx));
+            else
+                continue;
+        }
+        if (m_buildSetArray.item(idx).getProcessName() != NULL && strcmp(m_buildSetArray.item(idx).getProcessName(), XML_TAG_ESPSERVICE) == 0 && \
+                (m_buildSetArray.item(idx).getDeployable() != NULL && stricmp(m_buildSetArray.item(idx).getDeployable(), "no") == 0))
+            index--;
+    }
+
+    assert(!"index invalid");
+    return NULL;
+}

+ 122 - 0
configuration/configurator/BuildSet.hpp

@@ -0,0 +1,122 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _BUILD_SET_HPP_
+#define _BUILD_SET_HPP_
+
+#include "jstring.hpp"
+#include "jlib.hpp"
+
+namespace CONFIGURATOR
+{
+
+static const char* DEFAULT_BUILD_SET_XML_FILE("buildset.xml");
+static const char* DEFAULT_BUILD_SET_DIRECTORY("/opt/HPCCSystems/componentfiles/configxml/");
+
+class CBuildSet;
+
+class CBuildSetManager
+{
+public:
+
+    static CBuildSetManager* getInstance(const char* pBuildSetFile =  NULL, const char* pBuildSetDirectory = NULL);
+
+    virtual ~CBuildSetManager();
+    void getBuildSetComponents(::StringArray& buildSetArray) const;
+    void getBuildSetServices(::StringArray& buildSetArray) const;
+    void setBuildSetArray(const ::StringArray &strArray);
+    const char* getBuildSetServiceName(int index) const;
+    const char* getBuildSetServiceFileName(int index) const;
+    const char* getBuildSetComponentTypeName(int index) const;
+    const char* getBuildSetComponentFileName(int index) const;
+    const char* getBuildSetProcessName(int index) const;
+    const char* getBuildSetSchema(int index) const;
+    const int getBuildSetSchemaCount() const;
+    const int getBuildSetServiceCount() const;
+    const int getBuildSetComponentCount() const;
+    bool populateBuildSet();
+
+protected:
+
+    CBuildSetManager();
+    CBuildSetManager(const char* pBuildSetFile, const char* pBuildSetDir);
+    const CBuildSet* getBuildSetComponent(int index) const;
+    const CBuildSet* getBuildSetService(int index) const;
+    CIArrayOf<CBuildSet> m_buildSetArray;
+    Owned<IPropertyTree> m_buildSetTree;
+    StringBuffer m_buildSetFile;
+    StringBuffer m_buildSetDir;
+    StringBuffer m_buildSetPath;
+};
+
+
+class CBuildSet : public CInterface
+{
+public:
+
+    IMPLEMENT_IINTERFACE
+
+    CBuildSet(const char* pInstallSet = NULL, const char* pName = NULL, const char* pProcessName = NULL, const char* pSchema = NULL, const char* pDeployable = NULL, const char *pOveride = NULL) : m_pInstallSet(pInstallSet), m_pName(pName), m_pProcessName(pProcessName), m_pSchema(pSchema), m_pDeployable(pDeployable), m_pOveride(pOveride)
+    {
+    }
+
+    virtual ~CBuildSet()
+    {
+    }
+
+    const char* getInstallSet() const
+    {
+        return m_pInstallSet;
+    }
+    const char* getName() const
+    {
+        return m_pName;
+    }
+    const char* getProcessName() const
+    {
+        return m_pProcessName;
+    }
+    const char* getSchema() const
+    {
+        return m_pSchema;
+    }
+    const char* getDeployable() const
+    {
+        return m_pDeployable;
+    }
+    const char* getOveride() const
+    {
+        return m_pOveride;
+    }
+
+protected:
+
+    CBuildSet();
+    CBuildSet(const CBuildSet& buildSet) : m_pInstallSet(buildSet.m_pInstallSet), m_pName(buildSet.m_pName), m_pProcessName(buildSet.m_pProcessName), m_pSchema(buildSet.m_pSchema), m_pDeployable(buildSet.m_pDeployable)
+    {}
+    const char* m_pInstallSet;
+    const char* m_pName;
+    const char* m_pProcessName;
+    const char* m_pSchema;
+    const char* m_pDeployable;
+    const char* m_pOveride;
+
+private:
+};
+
+}
+#endif // _BUILD_SET_HPP_

+ 40 - 0
configuration/configurator/CMakeLists.txt

@@ -0,0 +1,40 @@
+project ( configurator )
+
+SET(  SRCS ConfiguratorMain.cpp ConfigFileComponentUtils.cpp ConfigFileUtils.cpp
+      ConfigFileUtilsObservable.cpp EnvironmentConfiguration.cpp WizardBase.cpp ConfigSchemaHelper.cpp
+      SchemaAttributes.cpp SchemaComplexType.cpp SchemaSequence.cpp SchemaElement.cpp
+      SchemaAppInfo.cpp SchemaAnnotation.cpp SchemaComplexContent.cpp SchemaComplexType.cpp SchemaDocumentation.cpp
+      SchemaExtension.cpp SchemaChoice.cpp SchemaInclude.cpp SchemaSchema.cpp SchemaSimpleType.cpp SchemaRestriction.cpp 
+      SchemaEnumeration.cpp SchemaCommon.cpp ExceptionStrings.cpp SchemaEnumeration.cpp SchemaAttributeGroup.cpp DocumentationMarkup.hpp
+      SchemaCommon.hpp BuildSet.cpp ConfiguratorAPI.cpp SchemaMapManager.cpp EnvironmentModel.cpp SchemaFractionDigits.cpp SchemaLength.cpp SchemaMaxExclusive.cpp
+      SchemaMaxInclusive.cpp SchemaMaxLength.cpp SchemaMinInclusive.cpp SchemaMinExclusive.cpp SchemaMinLength.cpp SchemaPattern.cpp SchemaTotalDigits.cpp SchemaWhiteSpace.cpp
+      SchemaKey.cpp SchemaKeyRef.cpp SchemaSelector.cpp SchemaUnique.cpp SchemaField.cpp SchemaSimpleContent.cpp ConfigNotifications.cpp JSONMarkUp.cpp)
+
+  INCLUDE_DIRECTORIES(
+        ${HPCC_SOURCE_DIR}/system/include
+        ${HPCC_SOURCE_DIR}/system/jlib
+        ${HPCC_SOURCE_DIR}/deployment/deploy
+        ${CMAKE_PREFIX_PATH}/mkspecs/linux-g++
+        ${CMAKE_CURRENT_SOURCE_DIR}/configurator_ui
+        ${CMAKE_CURRENT_SOURCE_DIR}/configurator_app
+)
+
+IF( CONFIGURATOR_LIB )
+    MESSAGE( "-- configurator target is a library file" )
+
+    ADD_DEFINITIONS( -D_USRDLL -DCONFIGURATOR_LIB)
+    HPCC_ADD_LIBRARY( configurator SHARED ${SRCS} )
+    TARGET_LINK_LIBRARIES( configurator jlib )
+
+    INSTALL( TARGETS configurator LIBRARY DESTINATION ${LIB_DIR} )
+
+ELSE ()
+    MESSAGE( "-- configurator target is a binary executable" )
+
+    ADD_DEFINITIONS( -D_CONSOLE )
+    HPCC_ADD_EXECUTABLE( configurator  ${SRCS} )
+    TARGET_LINK_LIBRARIES( configurator jlib )
+
+    INSTALL( TARGETS configurator RUNTIME DESTINATION ${EXEC_DIR} )
+
+ENDIF()

+ 56 - 0
configuration/configurator/ConfigFileComponentUtils.cpp

@@ -0,0 +1,56 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jexcept.hpp"
+
+#include "ConfigFileComponentUtils.hpp"
+
+//using namespace CONFIGURATOR;
+
+CConfigFileComponentUtils::CConfigFileComponentUtils()
+{
+    UNIMPLEMENTED;
+}
+
+CConfigFileComponentUtils::~CConfigFileComponentUtils()
+{
+    UNIMPLEMENTED;
+}
+
+void CConfigFileComponentUtils::getAvailableComponets(StringArray& compArray) const
+{
+    UNIMPLEMENTED;
+}
+
+void CConfigFileComponentUtils::getAvailableESPServices(StringArray& compArray) const
+{
+    UNIMPLEMENTED;
+}
+
+void CConfigFileComponentUtils::getDefinedDirectories(StringArray& definedDirectoriesArray) const
+{
+    UNIMPLEMENTED;
+}
+
+void CConfigFileComponentUtils::getDirectoryPath(const char *pkey, StringBuffer& path) const
+{
+    UNIMPLEMENTED;
+}
+
+void CConfigFileComponentUtils::setDirectoryPath(const char* pkey, const char* pval)
+{
+}

+ 49 - 0
configuration/configurator/ConfigFileComponentUtils.hpp

@@ -0,0 +1,49 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _CONFIG_FILE_COMPONENT_UTILS_HPP_
+#define _CONFIG_FILE_COMPONENT_UTILS_HPP_
+
+
+#include "jiface.hpp"
+#include "jutil.hpp"
+#include "jstring.hpp"
+
+//namespace CONFIGURATOR
+//{
+
+class CConfigFileComponentUtils : public CInterface
+{
+public:
+
+    IMPLEMENT_IINTERFACE
+
+    CConfigFileComponentUtils();
+    virtual ~CConfigFileComponentUtils();
+
+    void getAvailableComponets(::StringArray& compArray) const;
+    void getAvailableESPServices(::StringArray& compArray) const;
+    void getDefinedDirectories(::StringArray& definedDirectoriesArray) const;
+    void getDirectoryPath(const char *pkey, ::StringBuffer& path) const;
+    void setDirectoryPath(const char* pkey, const char* pval);
+
+protected:
+private:
+};
+
+//}
+#endif // _CONFIG_FILE_COMPONENT_UTILS_HPP_

+ 158 - 0
configuration/configurator/ConfigFileUtils.cpp

@@ -0,0 +1,158 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jfile.hpp"
+#include "jmutex.hpp"
+
+#include "ConfigFileUtils.hpp"
+
+using namespace CONFIGURATOR;
+
+CConfigFileUtils* CConfigFileUtils::getInstance()
+{
+    static Owned<CConfigFileUtils> s_configFileSingleton;
+    static CSingletonLock slock;
+
+    if (slock.lock() == true)
+    {
+      if (s_configFileSingleton.get() == NULL)
+        s_configFileSingleton.setown(new CConfigFileUtils(DEFAULT_CONFIGURATION_PATH));
+
+      slock.unlock();
+    }
+    return s_configFileSingleton.get();
+}
+
+CConfigFileUtils::CConfigFileUtils(const char* pDir, const char* pMask) : m_pDirPath(pDir), m_pMask(pMask)
+{
+}
+
+CConfigFileUtils::~CConfigFileUtils()
+{
+    closeConfigurationFile();
+}
+
+enum CConfigFileUtils::CF_ERROR_CODES CConfigFileUtils::createNewConfigurationFile(const char* pConfigFileName)
+{
+    notify(IConfigFileUtilsObserver::CF_FILE_CREATE_EVENT);
+    return CF_NO_ERROR;
+}
+
+enum CConfigFileUtils::CF_ERROR_CODES CConfigFileUtils::openConfigurationFile(const char* pConfigFileName)
+{
+    if (m_pFileIO.get() != NULL)
+        return CF_FILE_ALREADY_OPEN;
+    else if (m_pFileIO.get() == NULL)
+        return CF_FILE_NOT_OPEN;
+    else
+    {
+        m_pFile.setown(createIFile(pConfigFileName));
+        m_pFileIO.setown(m_pFile->open(IFOcreaterw));
+
+        notify(CONFIGURATOR::IConfigFileUtilsObserver::CF_FILE_OPEN_EVENT);
+        return CF_NO_ERROR;
+    }
+}
+
+enum CConfigFileUtils::CF_ERROR_CODES CConfigFileUtils::closeConfigurationFile()
+{
+    if (m_pFileIO.get() != NULL)
+    {
+        m_pFileIO->close();
+        m_pFileIO.clear();
+        m_pFile.clear();
+        notify(CONFIGURATOR::IConfigFileUtilsObserver::CF_FILE_CLOSE_EVENT);
+
+        return CF_NO_ERROR;
+    }
+    else
+        return CF_FILE_NOT_OPEN;
+}
+
+enum CConfigFileUtils::CF_ERROR_CODES CConfigFileUtils::writeToOpenConfigurationFile(const char* pBuffer, unsigned int length)
+{
+    if (length == 0)
+        return CF_WRITE_BUFFER_EMPTY;
+    else if (m_pFile.get() == NULL)
+        return CF_FILE_NOT_OPEN;
+    else
+    {
+        m_pFileIO->write(0, length, pBuffer);
+        notify(CONFIGURATOR::IConfigFileUtilsObserver::CF_FILE_WRITE_EVENT);
+        return CF_NO_ERROR;
+    }
+}
+
+enum CConfigFileUtils::CF_ERROR_CODES CConfigFileUtils::populateConfigFileArray()
+{
+    m_configFileArray.kill();
+
+    if (m_pDir.get() == NULL)
+    {
+        m_pDir.set(createIFile(m_pDirPath));
+
+        if ( (m_pDir.get() == NULL) || (m_pDir->exists() != true) || (m_pDir->isDirectory() == false) )
+            return CF_DIRECTORY_ACCESS_ERROR;
+    }
+
+    Owned<IDirectoryIterator> dirIter = m_pDir->directoryFiles(m_pMask);
+
+    if(dirIter.get() != NULL)
+    {
+        IFile &file = dirIter->query();
+        StringBuffer fname(file.queryFilename());
+        getFileNameOnly(fname, false);
+        m_configFileArray.append(fname);
+
+        return CF_NO_ERROR;
+    }
+    else
+        return CF_DIRECTORY_ACCESS_ERROR;
+}
+
+enum CConfigFileUtils::CF_ERROR_CODES CConfigFileUtils::writeConfigurationToFile(const char *pFilePath, const char* pBuffer, unsigned int length)
+{
+    assert(pBuffer != NULL);
+    assert(length != 0);
+    assert(pBuffer != NULL && *pBuffer != 0);
+
+    Owned<IFile>   pFile;
+    Owned<IFileIO> pFileIO;
+    IFileIO *pFIO = NULL;
+
+    pFile.setown(createIFile(pFilePath));
+
+    try
+    {
+        pFIO = pFile->open(IFOcreaterw);
+    }
+    catch(IErrnoException *pException)
+    {
+        pException->Release();
+    }
+
+
+    if (pFIO == NULL)
+        return CF_FILE_PERMISSIONS;
+
+    pFileIO.setown(pFIO);
+    pFileIO->write(0, length, pBuffer);
+    //notify(IConfigFileUtilsObserver::CF_FILE_WRITE_NO_CHECK);
+    notify(CONFIGURATOR::IConfigFileUtilsObserver::CF_FILE_WRITE_NO_CHECK);
+
+    return CF_NO_ERROR;
+}

+ 73 - 0
configuration/configurator/ConfigFileUtils.hpp

@@ -0,0 +1,73 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _CONFIG_FILE_HPP_
+#define _CONFIG_FILE_HPP_
+
+#include "jiface.hpp"
+#include "jmutex.hpp"
+#include "jutil.hpp"
+
+#include "ConfigFileUtilsObservable.hpp"
+
+namespace CONFIGURATOR
+{
+
+static const char* DEFAULT_CONFIGURATION_PATH("/etc/HPCCSystems/source/");
+static const char* DEFAULT_CONFIGURATION_MASK("*.xml");
+
+class CConfigFileUtils : public CConfigFileUtilsObservable
+{
+public:
+
+    enum CF_ERROR_CODES { CF_NO_ERROR = 0,
+                          CF_FILE_EXISTS,
+                          CF_FILE_PERMISSIONS,
+                          CF_FILE_NOT_OPEN,
+                          CF_FILE_ALREADY_OPEN,
+                          CF_FILE_DOES_NOT_EXIST,
+                          CF_WRITE_BUFFER_EMPTY,
+                          CF_DIRECTORY_ACCESS_ERROR,
+                          CF_OTHER = 99 };
+
+    static CConfigFileUtils* getInstance();
+    virtual ~CConfigFileUtils();
+    const StringArray& getAvailableConfigurationFiles() const;
+    enum CF_ERROR_CODES writeConfigurationToFile(const char *pFilePath, const char* pBuffer, unsigned int length);
+    enum CF_ERROR_CODES createNewConfigurationFile(const char* pConfigFileName);
+    enum CF_ERROR_CODES openConfigurationFile(const char* pConfigFileName);
+    enum CF_ERROR_CODES closeConfigurationFile();
+    enum CF_ERROR_CODES writeToOpenConfigurationFile(const char* pBuffer, unsigned int length);
+
+protected:
+
+    enum CF_ERROR_CODES populateConfigFileArray();
+
+private:
+
+    CConfigFileUtils(const char* pDir = DEFAULT_CONFIGURATION_PATH, const char* pMask = DEFAULT_CONFIGURATION_MASK);
+
+    StringArray     m_configFileArray;
+    const char*     m_pDirPath;
+    const char*     m_pMask;
+    Owned<IFile>    m_pDir;
+    Owned<IFile>    m_pFile;
+    Owned<IFileIO>  m_pFileIO;
+};
+
+}
+#endif // _CONFIG_FILE_HPP_

+ 50 - 0
configuration/configurator/ConfigFileUtilsObservable.cpp

@@ -0,0 +1,50 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "ConfigFileUtilsObservable.hpp"
+
+using namespace CONFIGURATOR;
+
+void CConfigFileUtilsObservable::addObserver(IConfigFileUtilsObserver& observer)
+{
+   CriticalBlock block(m_critsecObserverQueue);
+
+   //allow observers to register only once
+   if (m_qObservers.find(&observer) == (unsigned)-1)
+     m_qObservers.enqueue(&observer);
+}
+
+void CConfigFileUtilsObservable::removeObserver(IConfigFileUtilsObserver& observer)
+{
+    CriticalBlock block(m_critsecObserverQueue);
+    m_qObservers.dequeue(&observer);
+}
+
+void CConfigFileUtilsObservable::notify(enum IConfigFileUtilsObserver::CF_EVENT_TYPES eventType)
+{
+    CriticalBlock block(m_critsecObserverQueue);
+
+    for (unsigned int idxObservers = 0; idxObservers < m_qObservers.ordinality(); idxObservers++)
+    {
+        IConfigFileUtilsObserver *pConfigFileUtilsObserver = m_qObservers.query(idxObservers);
+
+        if (pConfigFileUtilsObserver->getEventType() == eventType || pConfigFileUtilsObserver->getEventType() == IConfigFileUtilsObserver::CF_FILE_ANY_EVENT)
+        {
+            //m_qObservers.query(idxObservers)->onNotify(eventType);
+        }
+    }
+}

+ 60 - 0
configuration/configurator/ConfigFileUtilsObservable.hpp

@@ -0,0 +1,60 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _CONFIG_FILE_UTILS_OBSERVALBE_HPP_
+#define _CONFIG_FILE_UTILS_OBSERVALBE_HPP_
+
+#include "jlib.hpp"
+#include "jqueue.tpp"
+#include "jmutex.hpp"
+
+#include "ConfigFileUtilsObserver.ipp"
+
+namespace CONFIGURATOR
+{
+
+
+class CConfigFileUtilsObservable : public CInterface, implements IObservable
+{
+public:
+    IMPLEMENT_IINTERFACE
+
+    virtual void addObserver(IConfigFileUtilsObserver& observer);
+    virtual void removeObserver(IConfigFileUtilsObserver& observer);
+
+    void enableNotifications(bool bEnable)
+    {
+        m_bEnableNotifications = bEnable;
+    }
+    bool getNotificationsEnabled() const
+    {
+        return m_bEnableNotifications;
+    }
+
+protected:
+
+    virtual void notify( enum IConfigFileUtilsObserver::CF_EVENT_TYPES eventType);
+
+private:
+
+    ::QueueOf<IConfigFileUtilsObserver,false> m_qObservers;
+    ::CriticalSection m_critsecObserverQueue;
+    bool m_bEnableNotifications;
+};
+
+}
+#endif // _CONFIG_FILE_UTILS_OBSERVALBE_HPP_

+ 26 - 0
configuration/configurator/ConfigFileUtilsObserver.ipp

@@ -0,0 +1,26 @@
+#ifndef _CONFIG_FILE_UTILS_OBSERVER_IPP_
+#define _CONFIG_FILE_UTILS_OBSERVER_IPP_
+
+#include "jobserve.hpp"
+
+namespace CONFIGURATOR
+{
+
+interface IConfigFileUtilsObserver : extends IObserver
+{
+public:
+
+    enum CF_EVENT_TYPES { CF_FILE_OPEN_EVENT = 0x1,
+                          CF_FILE_CLOSE_EVENT,
+                          CF_FILE_WRITE_EVENT,
+                          CF_FILE_DELETE_EVENT,
+                          CF_FILE_CREATE_EVENT,
+                          CF_FILE_WRITE_NO_CHECK,
+                          CF_FILE_ANY_EVENT,
+                          CF_FILE_OTHER_EVENT = 0xFF };
+
+    virtual enum CF_EVENT_TYPES getEventType() = 0;
+};
+
+}
+#endif // _CONFIG_FILE_UTILS_OBSERVER_IPP_

+ 106 - 0
configuration/configurator/ConfigNotifications.cpp

@@ -0,0 +1,106 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaCommon.hpp"
+#include "ConfigNotifications.hpp"
+#include "jlib.hpp"
+#include "jhash.ipp"
+#include "jhash.hpp"
+#include "jstring.hpp"
+
+using namespace CONFIGURATOR;
+
+CNotificationManager* CNotificationManager::s_pNotificationManager = NULL;
+
+CNotificationManager::CNotificationManager()
+{
+}
+
+CNotificationManager *CNotificationManager::getInstance()
+{
+    if (s_pNotificationManager == NULL)
+        s_pNotificationManager = new CNotificationManager();
+
+    return s_pNotificationManager;
+}
+
+int CNotificationManager::getNumberOfNotifications(enum ENotificationType eNotifyType) const
+{
+    int nCount = 0;
+    HashIterator iterHash(m_EnvXPathToNotification);
+
+    ForEach(iterHash)
+    {
+        CNotification *pNotification = m_EnvXPathToNotification.mapToValue(&iterHash.query());
+
+        for (int i = 0; i < eUnknown; i++)
+        {
+            nCount += pNotification->m_NotificationMessagesArrays[i].length();
+        }
+    }
+    return nCount;
+}
+
+void CNotificationManager::setNotification(const CXSDNodeBase *pNodeBase, enum ENotificationType eNotifyType, const char* pNotificationText)
+{
+    assert (pNodeBase != NULL);
+    assert (pNotificationText != NULL);
+
+    if (pNodeBase != NULL)
+    {
+        const char* pEnvXPath = pNodeBase->getEnvXPath();
+
+        assert(pEnvXPath != NULL && *pEnvXPath != 0);
+        if (pEnvXPath != NULL)
+        {
+            CNotification *pNotification = m_EnvXPathToNotification.getValue(pEnvXPath);
+
+            if (pNotification == NULL)
+            {
+                pNotification = new CNotification();
+                m_EnvXPathToNotification.setValue(pEnvXPath, pNotification);
+            }
+            pNotification->m_NotificationMessagesArrays[eNotifyType].append(pNotificationText);
+        }
+    }
+}
+
+void CNotificationManager::resetNotifications(const CXSDNodeBase *pNodeBase)
+{
+    assert(pNodeBase != NULL);
+    if (pNodeBase != NULL)
+    {
+        const char* pEnvXPath = pNodeBase->getEnvXPath();
+
+        assert(pEnvXPath != NULL && *pEnvXPath != 0);
+
+        if (pEnvXPath != NULL && *pEnvXPath != 0)
+        {
+            CNotification *pNotification = m_EnvXPathToNotification.getValue(pEnvXPath);
+
+            if (pNotification != NULL)
+            {
+                m_EnvXPathToNotification.remove(pEnvXPath);
+                delete pNotification;
+            }
+        }
+    }
+}
+const char* CNotificationManager::getNotification(enum ENotificationType eNotifyType, int idx) const
+{
+    return NULL;
+}

+ 103 - 0
configuration/configurator/ConfigNotifications.hpp

@@ -0,0 +1,103 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _CONFIG_NOTIFICATIONS_HPP_
+#define _CONFIG_NOTIFICATIONS_HPP_
+
+#include "jiface.hpp"
+#include "jhash.ipp"
+#include "jutil.hpp"
+
+namespace CONFIGURATOR
+{
+
+enum ENotificationType
+{
+    eInformational = 1,
+    eAlert,
+    eWarning,
+    eError,
+    eCritical,
+    eUnknown // needs to be last
+};
+
+static const char NotificationTypeNames[eUnknown][1024] = {     "Informational",
+                                                                "Alert",
+                                                                "Warning",
+                                                                "Error",
+                                                                "Critical",
+                                                                "Unknown" };
+
+class CNotification;
+class CNotificationManager;
+
+class CNotificationManager : public InterfaceImpl
+{
+public:
+
+    static CNotificationManager* getInstance();
+
+    virtual ~CNotificationManager(){}
+
+    int getNumberOfNotificationTypes() const
+    {
+        return eUnknown-1;
+    }
+
+    const char* getNotificationTypeName(int idx)
+    {
+        if (idx >= 0 && idx < eUnknown)
+            return NotificationTypeNames[idx];
+        else
+            return NULL;
+    }
+
+    int getNumberOfNotifications(enum ENotificationType eNotifyType) const;
+    const char* getNotification(enum ENotificationType eNotifyType, int idx) const;
+
+    void setNotification(const CXSDNodeBase *pNodeBase, enum ENotificationType eNotifyType, const char* pNotificationText);
+    void resetNotifications(const CXSDNodeBase *pNodeBase);
+
+protected:
+
+    CNotificationManager();
+
+    typedef MapStringToMyClass<CNotification> MapStringToCNotification;
+    MapStringToCNotification m_EnvXPathToNotification;
+
+private:
+
+    static CNotificationManager *s_pNotificationManager;
+};
+
+class CNotification : public InterfaceImpl
+{
+    friend class CNotificationManager;
+
+public:
+
+    CNotification()
+    {
+    }
+    virtual ~CNotification()
+    {
+    }
+    StringArray m_NotificationMessagesArrays[eUnknown];
+};
+
+}
+#endif // _CONFIG_NOTIFICATIONS_HPP_

+ 898 - 0
configuration/configurator/ConfigSchemaHelper.cpp

@@ -0,0 +1,898 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jptree.hpp"
+#include "XMLTags.h"
+#include <cstring>
+#include "jfile.hpp"
+
+#include "ConfigSchemaHelper.hpp"
+#include "SchemaAttributes.hpp"
+#include "SchemaElement.hpp"
+#include "SchemaEnumeration.hpp"
+#include "ExceptionStrings.hpp"
+#include "BuildSet.hpp"
+#include "SchemaMapManager.hpp"
+#include "ConfigSchemaHelper.hpp"
+#include "ConfigFileUtils.hpp"
+#include "JSONMarkUp.hpp"
+
+
+#define SUCCESS 0
+#define FAILURE 1
+#define LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET \
+int nComponentCount = CBuildSetManager::getInstance()->getBuildSetComponentCount();         \
+\
+for (int idx = 0; idx < nComponentCount; idx++)
+
+using namespace CONFIGURATOR;
+
+
+
+CConfigSchemaHelper* CConfigSchemaHelper::s_pCConfigSchemaHelper = NULL;
+
+CConfigSchemaHelper* CConfigSchemaHelper::getInstance(const char* pDefaultDirOverride)
+{
+    // not thread safe!!!
+    if (s_pCConfigSchemaHelper == NULL)
+    {
+        s_pCConfigSchemaHelper = new CConfigSchemaHelper();
+        s_pCConfigSchemaHelper->m_nTables = 0;
+
+        if (pDefaultDirOverride != NULL && pDefaultDirOverride[0] != 0)
+            s_pCConfigSchemaHelper->setBasePath(pDefaultDirOverride);
+    }
+    return s_pCConfigSchemaHelper;
+}
+
+CConfigSchemaHelper* CConfigSchemaHelper::getInstance(const char* pBuildSetFileName, const char *pBaseDirectory, const char *pDefaultDirOverride)
+{
+    assert(pBuildSetFileName != NULL);
+    assert(pBaseDirectory != NULL);
+
+    if (s_pCConfigSchemaHelper == NULL && pBuildSetFileName != NULL && pBaseDirectory != NULL)
+    {
+       s_pCConfigSchemaHelper = new CConfigSchemaHelper(pBuildSetFileName, pBaseDirectory, pDefaultDirOverride);
+       s_pCConfigSchemaHelper->m_nTables = 0;
+    }
+    return s_pCConfigSchemaHelper;
+}
+
+CConfigSchemaHelper::CConfigSchemaHelper(const char* pBuildSetFile, const char* pBuildSetDir, const char* pDefaultDirOverride) : m_pBasePath(NULL), m_nTables(0),\
+    m_pEnvPropertyTree(NULL), m_pSchemaMapManager(NULL)
+{
+    assert(pBuildSetFile != NULL);
+    assert(pBuildSetDir != NULL);
+
+    CBuildSetManager::getInstance(pBuildSetFile, pBuildSetDir);
+    m_pSchemaMapManager = new CSchemaMapManager();
+}
+
+CConfigSchemaHelper::~CConfigSchemaHelper()
+{
+    delete[] m_pBasePath;
+    delete CConfigSchemaHelper::m_pSchemaMapManager;
+    CConfigSchemaHelper::m_pSchemaMapManager = NULL;
+    CConfigSchemaHelper::s_pCConfigSchemaHelper = NULL;
+}
+
+bool CConfigSchemaHelper::populateSchema()
+{
+    assert(m_pSchemaMapManager != NULL);
+
+    LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
+    {
+        const char *pSchemaName = CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx);
+
+        if (pSchemaName != NULL)
+        {
+            CXSDNodeBase *pNull = NULL;
+            CSchema *pSchema = CSchema::load(pSchemaName, pNull);
+
+            assert(pSchema->getLinkCount() == 1);
+            m_pSchemaMapManager->setSchemaForXSD(pSchemaName, pSchema);
+        }
+    }
+    populateEnvXPath();
+
+    return true;
+}
+
+void CConfigSchemaHelper::printConfigSchema(StringBuffer &strXML) const
+{
+    assert(m_pSchemaMapManager != NULL);
+
+    const char *pComponent = NULL;
+    CSchema* pSchema = NULL;
+
+    LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
+    {
+        const char *pSchemaName = CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx);
+
+        if (pComponent == NULL || strcmp(pComponent, pSchemaName) == 0)
+        {
+            const char* pXSDSchema = pSchemaName;
+
+            if (pXSDSchema == NULL)
+                continue;
+
+            pSchema = m_pSchemaMapManager->getSchemaForXSD(pSchemaName);
+
+            if (pSchema != NULL)
+            {
+                if (strXML.length() > 0 ? strcmp(strXML.str(), pXSDSchema) == 0 : true)
+                    pSchema->dump(::std::cout);
+            }
+        }
+    }
+}
+
+const char* CConfigSchemaHelper::printDocumentation(const char* comp)
+{
+    assert(comp != NULL && *comp != 0);
+    assert(m_pSchemaMapManager != NULL);
+
+    if (comp == NULL || *comp == 0)
+        return NULL;
+
+    CSchema* pSchema = NULL;
+
+    LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
+    {
+        const char *pSchemaName = CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx);
+
+        if (pSchemaName != NULL && strcmp(comp, pSchemaName) == 0)
+        {
+             pSchema = m_pSchemaMapManager->getSchemaForXSD(pSchemaName);
+
+             assert(pSchema != NULL);
+
+             if (pSchema != NULL)
+             {
+                static StringBuffer strDoc;
+                strDoc.clear(); // needed when printing more than 1 component
+                pSchema->getDocumentation(strDoc);
+
+                return strDoc.str();
+             }
+        }
+    }
+    return NULL;
+}
+void CConfigSchemaHelper::printJSON(const char* comp, char **pOutput, int nIdx, bool bCleanUp) const
+{
+    if (! (comp != NULL && *comp != 0) )
+    {
+        DBGLOG("no component selected for JSON, index = %d", nIdx);
+        return;
+    }
+    assert(m_pSchemaMapManager != NULL);
+
+    StringBuffer strJSON;
+
+    strJSON.clear();
+    resetTables();
+
+    CSchema* pSchema = NULL;
+
+    LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
+    {
+        const char *pSchemaName = CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx);
+        //const char *pSchemaName = CBuildSetManager::getInstance()->getBuildSetComponentName(idx);
+
+        if (pSchemaName != NULL && strcmp(comp, pSchemaName) == 0)
+        {
+            pSchema = m_pSchemaMapManager->getSchemaForXSD(pSchemaName);
+            assert(pSchema != NULL);
+
+            if (pSchema != NULL)
+            {
+                pSchema->getJSON(strJSON, 0, nIdx);
+                *pOutput = (char*)malloc((sizeof(char))* (strJSON.length())+1);
+
+                if (bCleanUp == true)
+                {
+                    this->clearLF(strJSON);
+                    strJSON.replaceString("\\","\\\\");
+                }
+
+                sprintf(*pOutput,"%s",strJSON.str());
+
+                return;
+            }
+            else
+            {
+                *pOutput = NULL;
+            }
+        }
+    }
+}
+
+void CConfigSchemaHelper::printJSONByKey(const char* key, char **pOutput, bool bCleanUp) const
+{
+    if (! (key != NULL && *key != 0) )
+    {
+        DBGLOG("no component key provided for to generate JSON");
+        return;
+    }
+
+    assert(m_pSchemaMapManager != NULL);
+
+    if (key[0] == '#')
+        key = &(key[1]);
+
+    StringBuffer strKey(key);
+    StringBuffer strJSON;
+
+    strJSON.clear();
+    resetTables();
+
+    const char *pChar = strrchr(key,'[');
+    assert(pChar != NULL && strlen(pChar) >= 3);
+
+    int length = strlen(pChar);
+
+    StringBuffer strIdx;
+
+    pChar++;
+
+    int nTemp = 0;
+
+    do
+    {
+        strIdx.append(*(pChar+nTemp));
+        nTemp++;
+    }while (*(pChar+nTemp) != ']');
+
+    int nIndexForJSON = atoi(strIdx.str());
+
+    strKey.setLength(strKey.length()-length);  // remove [N] from XPath;
+
+    CSchema* pSchema = NULL;
+
+    LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
+    {
+        const char *pProcessName = CBuildSetManager::getInstance()->getBuildSetProcessName(idx);
+
+        if (pProcessName != NULL && strcmp(strKey.str(), pProcessName) == 0)
+        {
+            pSchema = m_pSchemaMapManager->getSchemaForXSD(CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx));
+            assert(pSchema != NULL);
+
+            if (pSchema != NULL)
+            {
+                pSchema->getJSON(strJSON, 0, nIndexForJSON-1);
+                *pOutput = (char*)malloc((sizeof(char))* (strJSON.length())+1);
+
+                if (bCleanUp == true)
+                {
+                    this->clearLF(strJSON);
+                    strJSON.replaceString("\\","\\\\");
+                }
+
+                sprintf(*pOutput,"%s",strJSON.str());
+
+                return;
+            }
+            else
+            {
+                *pOutput = NULL;
+            }
+        }
+    }
+}
+
+void CConfigSchemaHelper::printNavigatorJSON(char **pOutput, bool bCleanUp) const
+{
+    StringBuffer strJSON;
+
+    CJSONMarkUpHelper::getNavigatorJSON(strJSON);
+
+    if (strJSON.length() == 0)
+        *pOutput = NULL;
+
+    *pOutput = (char*)malloc((sizeof(char))* (strJSON.length())+1);
+
+    if (bCleanUp == true)
+    {
+        this->clearLF(strJSON);
+        strJSON.replaceString("\\","\\\\");
+    }
+
+    sprintf(*pOutput,"%s",strJSON.str());
+
+    return;
+}
+
+void CConfigSchemaHelper::printDump(const char* comp) const
+{
+    assert(comp != NULL && *comp != 0);
+    assert(m_pSchemaMapManager != NULL);
+
+    if (comp == NULL || *comp == 0)
+        return;
+
+    CSchema* pSchema = NULL;
+
+    LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
+    {
+        const char *pSchemaName = CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx);
+
+        if (pSchemaName != NULL && strcmp(comp, pSchemaName) == 0)
+        {
+             pSchema = m_pSchemaMapManager->getSchemaForXSD(pSchemaName);
+             assert(pSchema != NULL);
+
+             if (pSchema != NULL)
+                pSchema->dump(::std::cout);
+        }
+    }
+}
+
+//test purposes
+bool CConfigSchemaHelper::getXMLFromSchema(StringBuffer& strXML, const char* pComponent)
+{
+    assert (m_pSchemaMapManager != NULL);
+
+    CAttributeArray *pAttributeArray = NULL;
+    CElementArray *pElementArray = NULL;
+    CSchema* pSchema = NULL;
+
+    strXML.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Environment>\n\t<Software>");
+
+    LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
+    {
+        const char *pSchemaName = CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx);
+
+        if (pComponent == NULL || strcmp(pComponent, pSchemaName) == 0)
+        {
+            if (pSchemaName == NULL)
+                continue;
+
+            pSchema =  m_pSchemaMapManager->getSchemaForXSD(pSchemaName);
+
+            if (pSchema != NULL)
+                strXML.append(pSchema->getXML(NULL));
+        }
+    }
+    strXML.append("\t</Software>\n</Environment>\n");
+
+    return true;
+}
+
+void CConfigSchemaHelper::addExtensionToBeProcessed(CExtension *pExtension)
+{
+    assert(pExtension != NULL);
+    if (pExtension != NULL)
+        m_extensionArr.append(*pExtension);
+}
+
+void CConfigSchemaHelper::addAttributeGroupToBeProcessed(CAttributeGroup *pAttributeGroup)
+{
+    assert(pAttributeGroup != NULL);
+    if (pAttributeGroup != NULL)
+        m_attributeGroupArr.append(*pAttributeGroup);
+}
+
+void CConfigSchemaHelper::addNodeForTypeProcessing(CXSDNodeWithType *pNode)
+{
+    assert(pNode != NULL);
+    if (pNode != NULL)
+        m_nodeWithTypeArr.append(*pNode);
+}
+
+void CConfigSchemaHelper::addNodeForBaseProcessing(CXSDNodeWithBase *pNode)
+{
+    assert(pNode != NULL);
+    if (pNode != NULL)
+        m_nodeWithBaseArr.append(*pNode);
+}
+
+void CConfigSchemaHelper::processExtensionArr()
+{
+    int length = m_extensionArr.length();
+
+    for (int idx = 0; idx < length; idx++)
+    {
+        CExtension &Extension = (m_extensionArr.item(idx));
+        const char *pName = Extension.getBase();
+
+        assert(pName != NULL);
+
+        if (pName != NULL)
+        {
+            CXSDNode *pNodeBase = NULL;
+            pNodeBase = m_pSchemaMapManager->getSimpleTypeWithName(pName) != NULL ? dynamic_cast<CSimpleType*>(m_pSchemaMapManager->getSimpleTypeWithName(pName)) : NULL;
+
+            if (pNodeBase == NULL)
+                pNodeBase = m_pSchemaMapManager->getComplexTypeWithName(pName) != NULL ? dynamic_cast<CComplexType*>(m_pSchemaMapManager->getComplexTypeWithName(pName)) : NULL ;
+
+            assert(pNodeBase != NULL);
+
+            if (pNodeBase != NULL)
+                Extension.setBaseNode(pNodeBase);
+        }
+    }
+    m_extensionArr.popAll(false);
+}
+
+void CConfigSchemaHelper::processAttributeGroupArr()
+{
+    aindex_t length = m_attributeGroupArr.length();
+
+    for (aindex_t idx = 0; idx < length; idx++)
+    {
+        CAttributeGroup &AttributeGroup = (m_attributeGroupArr.item(idx));
+        const char *pRef = AttributeGroup.getRef();
+
+        assert(pRef != NULL && pRef[0] != 0);
+        if (pRef != NULL && pRef[0] != 0)
+        {
+            assert(m_pSchemaMapManager != NULL);
+            CAttributeGroup *pAttributeGroup = m_pSchemaMapManager->getAttributeGroupFromXPath(pRef);
+
+            assert(pAttributeGroup != NULL);
+            if (pAttributeGroup != NULL)
+                AttributeGroup.setRefNode(pAttributeGroup);
+        }
+    }
+    m_attributeGroupArr.popAll(true);
+}
+
+void CConfigSchemaHelper::processNodeWithTypeArr(CXSDNodeBase *pParentNode)
+{
+    int length = m_nodeWithTypeArr.length();
+
+    for (int idx = 0; idx < length; idx++)
+    {
+        CXSDNodeWithType *pNodeWithType = &(m_nodeWithTypeArr.item(idx));
+        const char *pTypeName = pNodeWithType->getType();
+
+        assert(pTypeName != NULL);
+        if (pTypeName != NULL)
+        {
+            CXSDNode *pNode = NULL;
+            pNode = m_pSchemaMapManager->getSimpleTypeWithName(pTypeName) != NULL ? dynamic_cast<CSimpleType*>(m_pSchemaMapManager->getSimpleTypeWithName(pTypeName)) : NULL;
+
+            if (pNode == NULL)
+                pNode = m_pSchemaMapManager->getComplexTypeWithName(pTypeName) != NULL ? dynamic_cast<CComplexType*>(m_pSchemaMapManager->getComplexTypeWithName(pTypeName)) : NULL;
+            if (pNode == NULL)
+                pNode = CXSDBuiltInDataType::create(pNodeWithType, pTypeName);
+            if (pNode != NULL)
+                pNodeWithType->setTypeNode(pNode);
+            else
+                PROGLOG("Unsupported type '%s'", pTypeName);
+        }
+    }
+    m_nodeWithTypeArr.popAll(true);
+}
+
+void CConfigSchemaHelper::processNodeWithBaseArr()
+{
+    int length = m_nodeWithBaseArr.length();
+
+    for (int idx = 0; idx < length; idx++)
+    {
+        CXSDNodeWithBase *pNodeWithBase = &(this->m_nodeWithBaseArr.item(idx));
+        const char *pBaseName = pNodeWithBase->getBase();
+
+        assert(pBaseName != NULL);
+        if (pBaseName != NULL)
+        {
+            CXSDNode *pNode = NULL;
+            pNode = m_pSchemaMapManager->getSimpleTypeWithName(pBaseName) != NULL ? dynamic_cast<CSimpleType*>(m_pSchemaMapManager->getSimpleTypeWithName(pBaseName)) : NULL;
+
+            if (pNode == NULL)
+                pNode = m_pSchemaMapManager->getComplexTypeWithName(pBaseName) != NULL ? dynamic_cast<CComplexType*>(m_pSchemaMapManager->getComplexTypeWithName(pBaseName)) : NULL;
+            if (pNode == NULL)
+                pNode = CXSDBuiltInDataType::create(pNode, pBaseName);
+
+            assert(pNode != NULL);
+            if (pNode != NULL)
+                pNodeWithBase->setBaseNode(pNode);
+            else
+                PROGLOG("Unsupported type '%s'", pBaseName);
+        }
+    }
+    m_nodeWithBaseArr.popAll(false);
+}
+
+void CConfigSchemaHelper::addElementForRefProcessing(CElement *pElement)
+{
+    assert (pElement != NULL);
+    if (pElement != NULL)
+        m_ElementArr.append(*pElement);
+}
+
+void CConfigSchemaHelper::processElementArr(CElement *pElement)
+{
+    int length = m_nodeWithBaseArr.length();
+
+    for (int idx = 0; idx < length; idx++)
+    {
+        CElement *pElement = &(this->m_ElementArr.item(idx));
+        const char *pRef = pElement->getRef();
+
+        assert(pRef != NULL);
+        if (pRef != NULL)
+        {
+            CElement *pRefElementNode = NULL;
+            pRefElementNode = m_pSchemaMapManager->getElementWithName(pRef);
+
+            if (pRefElementNode != NULL)
+                pElement->setRefElementNode(pRefElementNode);
+            else
+                //TODO: throw exception
+                assert(!"Unknown element referenced");
+        }
+    }
+    m_ElementArr.popAll(false);
+}
+
+void CConfigSchemaHelper::populateEnvXPath()
+{
+    CSchema* pSchema = NULL;
+    StringBuffer strXPath;
+
+    LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
+    {
+        pSchema = m_pSchemaMapManager->getSchemaForXSD(CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx));
+
+        if (pSchema != NULL)
+            pSchema->populateEnvXPath(strXPath);
+    }
+}
+
+void CConfigSchemaHelper::loadEnvFromConfig(const char *pEnvFile)
+{
+    assert(pEnvFile != NULL);
+
+    typedef ::IPropertyTree PT;
+    Linked<PT> pEnvXMLRoot;
+
+    try
+    {
+        pEnvXMLRoot.setown(createPTreeFromXMLFile(pEnvFile));
+    }
+    catch (...)
+    {
+        CONFIGURATOR::MakeExceptionFromMap(EX_STR_CAN_NOT_PROCESS_ENV_XML);
+    }
+
+    CSchema* pSchema = NULL;
+
+    this->setEnvPropertyTree(pEnvXMLRoot.getLink());
+    this->setEnvFilePath(pEnvFile);
+
+    LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
+    {
+        pSchema = m_pSchemaMapManager->getSchemaForXSD(CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx));
+
+        if (pSchema != NULL)
+            pSchema->loadXMLFromEnvXml(pEnvXMLRoot);
+    }
+}
+
+void CConfigSchemaHelper::addToolTip(const char *js)
+{
+    assert (js != NULL);
+    assert (js[0] != 0);
+
+    if (js == NULL || js[0] == 0)
+        return;
+
+    m_strToolTipsJS.append(js);
+}
+
+const char* CConfigSchemaHelper::getToolTipJS() const
+{
+    static StringBuffer strJS;
+    strJS.clear();
+
+    for (int idx = 0; idx < m_strToolTipsJS.length(); idx++)
+    {
+        strJS.append(m_strToolTipsJS.item(idx));
+    }
+    return strJS.str();
+}
+
+void CConfigSchemaHelper::setEnvTreeProp(const char *pXPath, const char* pValue)
+{
+    assert(pXPath != NULL && pXPath[0] != 0);
+    assert(m_pSchemaMapManager != NULL);
+
+    CAttribute *pAttribute = m_pSchemaMapManager->getAttributeFromXPath(pXPath);
+    assert(pAttribute != NULL);
+
+    StringBuffer strPropName("@");
+    strPropName.append(pAttribute->getName());
+
+    if (this->getEnvPropertyTree()->queryPropTree(pAttribute->getConstAncestorNode(1)->getEnvXPath())->queryProp(strPropName.str()) == NULL)
+        //should check if this attribute is optional for validation
+        this->getEnvPropertyTree()->queryPropTree(pAttribute->getConstAncestorNode(1)->getEnvXPath())->setProp(strPropName.str(), pValue);
+    else if (strcmp (this->getEnvPropertyTree()->queryPropTree(pAttribute->getConstAncestorNode(1)->getEnvXPath())->queryProp(strPropName.str()), pValue) == 0)
+        return; // nothing changed
+    else
+        this->getEnvPropertyTree()->queryPropTree(pAttribute->getConstAncestorNode(1)->getEnvXPath())->setProp(strPropName.str(), pValue);
+}
+
+const char* CConfigSchemaHelper::getTableValue(const char* pXPath,  int nRow) const
+{
+    assert(pXPath != NULL);
+    assert(m_pSchemaMapManager != NULL);
+
+    CAttribute *pAttribute = m_pSchemaMapManager->getAttributeFromXPath(pXPath);
+    CElement *pElement = NULL;
+
+    if (pAttribute == NULL)
+    {
+        pElement = m_pSchemaMapManager->getElementFromXPath(pXPath);
+        assert(pElement != NULL);
+        return pElement->getEnvValueFromXML();
+    }
+    else
+    {
+        assert(pAttribute != NULL);
+        if (nRow == 1)
+            return pAttribute->getEnvValueFromXML();
+        else
+        {
+            StringBuffer strXPath(pXPath);
+            StringBuffer strXPathOrignal(pXPath);
+
+            CConfigSchemaHelper::stripXPathIndex(strXPath);
+
+            strXPath.appendf("[%d]", nRow);
+            char pTemp[64];
+            int offset = strXPath.length() - (strlen(itoa(nRow, pTemp, 10)) - 1);
+
+            strXPath.append(strXPathOrignal, strXPath.length(), strXPathOrignal.length()-offset);
+
+            pAttribute = m_pSchemaMapManager->getAttributeFromXPath(strXPath.str());
+
+            if (pAttribute == NULL)
+                return NULL;
+
+            return pAttribute->getEnvValueFromXML();
+        }
+    }
+}
+
+int CConfigSchemaHelper::getElementArraySize(const char *pXPath) const
+{
+    assert(pXPath != NULL);
+    assert(m_pSchemaMapManager != NULL);
+
+    //CElementArray *pElementArray = m_pSchemaMapManager->getElementArrayFromXSDXPath(pXPath);
+    CElementArray *pElementArray = m_pSchemaMapManager->getElementArrayFromXPath(pXPath);
+
+    if (pElementArray == NULL)
+        return 0;
+
+    //return pElementArray->getCountOfSiblingElements(pXPath);
+    VStringBuffer strXPath("%s[1]",pElementArray->getXSDXPath());
+    //return pElementArray->getCountOfSiblingElements(pElementArray->getXSDXPath());
+    return pElementArray->getCountOfSiblingElements(strXPath.str());
+}
+
+const char* CConfigSchemaHelper::getAttributeXSDXPathFromEnvXPath(const char* pEnvXPath) const
+{
+    assert(pEnvXPath != NULL && *pEnvXPath != 0);
+    assert(m_pSchemaMapManager != NULL);
+    CAttribute *pAttribute = m_pSchemaMapManager->getAttributeFromXPath(pEnvXPath);
+
+    assert(pAttribute != NULL);
+    return pAttribute->getXSDXPath();
+}
+
+const char* CConfigSchemaHelper::getElementArrayXSDXPathFromEnvXPath(const char* pXSDXPath) const
+{
+    assert(pXSDXPath != NULL);
+    assert(m_pSchemaMapManager != NULL);
+    CElementArray *pElementArray = m_pSchemaMapManager->getElementArrayFromXSDXPath(pXSDXPath);
+
+    assert(pElementArray != NULL);
+    return pElementArray->getXSDXPath();
+}
+
+void CConfigSchemaHelper::appendAttributeXPath(const char* pXPath)
+{
+    m_strArrayEnvXPaths.append(pXPath);
+}
+
+void CConfigSchemaHelper::appendElementXPath(const char* pXPath)
+{
+    m_strArrayEnvXPaths.append(pXPath);
+}
+
+int CConfigSchemaHelper::stripXPathIndex(StringBuffer &strXPath)
+{
+    int nLen = strXPath.length()-3;
+    int nLengthOfStringInBracket = 3;
+
+    while (nLen > 0)
+    {
+        if (strXPath[nLen] == '[')
+        {
+            strXPath.reverse().remove(0,strXPath.length()-nLen).reverse();
+            return nLengthOfStringInBracket;
+        }
+        nLen--;
+        nLengthOfStringInBracket++;
+    }
+    return nLengthOfStringInBracket;
+}
+
+bool CConfigSchemaHelper::isXPathTailAttribute(const StringBuffer &strXPath)
+{
+    int nLen = strXPath.length()-3;
+
+    while (nLen > 0)
+    {
+        if (strXPath[nLen] == '[')
+        {
+            if (strXPath[nLen+1] == '@')
+                return true;
+            else
+                return false;
+        }
+        nLen--;
+    }
+    assert(!"Control should not reach here");
+    return false;
+}
+
+void CConfigSchemaHelper::setBasePath(const char *pBasePath)
+{
+    assert(m_pBasePath == NULL);
+    int nLength = strlen(pBasePath);
+    m_pBasePath = new char[nLength+1];
+    strcpy(m_pBasePath, pBasePath);
+}
+
+
+bool CConfigSchemaHelper::saveConfigurationFile() const
+{
+    assert(m_strEnvFilePath.length() != 0);
+
+    if (m_strEnvFilePath.length() == 0)
+        return false;
+
+    if (this->getConstEnvPropertyTree() == NULL)
+        return false;
+
+    StringBuffer strXML;
+    strXML.appendf("<" XML_HEADER ">\n<!-- Edited with THE CONFIGURATOR -->\n");
+    ::toXML(this->getConstEnvPropertyTree(), strXML, 0, XML_SortTags | XML_Format);
+
+    if (CConfigFileUtils::getInstance()->writeConfigurationToFile(m_strEnvFilePath.str(), strXML.str(), strXML.length()) == CConfigFileUtils::CF_NO_ERROR)
+        return true;
+    else
+        return false;
+}
+
+bool CConfigSchemaHelper::saveConfigurationFileAs(const char *pFilePath)
+{
+    assert(pFilePath && *pFilePath);
+
+    if (pFilePath == NULL || *pFilePath == 0)
+        return false;
+
+    if (this->getConstEnvPropertyTree() == NULL)
+        return false;
+
+    StringBuffer strXML;
+    strXML.appendf("<" XML_HEADER ">\n<!-- Edited with THE CONFIGURATOR -->\n");
+    ::toXML(this->getConstEnvPropertyTree(), strXML, 0, XML_SortTags | XML_Format);
+
+    if (CConfigFileUtils::getInstance()->writeConfigurationToFile(pFilePath, strXML.str(), strXML.length()) == CConfigFileUtils::CF_NO_ERROR)
+    {
+        m_strEnvFilePath.set(pFilePath);
+        return true;
+    }
+    else
+        return false;
+}
+
+void CConfigSchemaHelper::addKeyRefForReverseAssociation(const CKeyRef *pKeyRef) const
+{
+}
+
+void CConfigSchemaHelper::processKeyRefReverseAssociation() const
+{
+}
+
+void CConfigSchemaHelper::addKeyForReverseAssociation(const CKey *pKeyRef) const
+{
+}
+
+void CConfigSchemaHelper::processKeyReverseAssociation() const
+{
+}
+
+int CConfigSchemaHelper::getInstancesOfComponentType(const char *pCompType) const
+{
+    assert(pCompType != NULL && *pCompType != 0);
+
+    LOOP_THRU_BUILD_SET_MANAGER_BUILD_SET
+    {
+        const char *pCompName = CBuildSetManager::getInstance()->getBuildSetComponentTypeName(idx);//  ->getBuildSetProcessName(idx);
+        const char *pProcessName = CBuildSetManager::getInstance()->getBuildSetProcessName(idx);
+
+        if (pCompName != NULL && strcmp(pCompName, pCompType) == 0)
+        {
+             CSchema *pSchema = m_pSchemaMapManager->getSchemaForXSD(CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx));
+
+             assert(pSchema != NULL);
+
+             if (pSchema == NULL)
+                 return FAILURE;
+
+             int nCount = 0;
+             ::VStringBuffer strXPath("./%s/%s[%d]", XML_TAG_SOFTWARE, pProcessName, 1);
+
+             while (true)
+             {
+                 ::IPropertyTree *pTree = CConfigSchemaHelper::getInstance()->getEnvPropertyTree();
+
+                 if (pTree == NULL)
+                     return FAILURE;
+
+                 if (pTree->queryPropTree(strXPath.str()) == NULL)
+                     return nCount;
+
+                 nCount++;
+                 strXPath.setf("./%s/%s[%d]", XML_TAG_SOFTWARE, pProcessName, nCount+1);
+             }
+        }
+    }
+    return SUCCESS;
+}
+
+const char* CConfigSchemaHelper::getInstanceNameOfComponentType(const char *pCompType, int idx)
+{
+    if (pCompType == NULL || *pCompType == 0)
+        return NULL;  // throw exception?
+    if (this->getEnvPropertyTree() == NULL)
+        return NULL;  // throw exception?
+
+    ::VStringBuffer strXPath("./%s/%s[%d]", XML_TAG_SOFTWARE, pCompType, idx+1);
+
+    typedef ::IPropertyTree jlibIPropertyTree;
+    const ::IPropertyTree *pTree = const_cast<const jlibIPropertyTree*>(this->getEnvPropertyTree()->queryPropTree(strXPath.str()));
+
+    return pTree->queryProp(XML_ATTR_NAME);
+}
+
+void CConfigSchemaHelper::clearLF(::StringBuffer& strToClear)
+{
+    strToClear.replaceString("\n","");
+}
+
+CConfigSchemaHelper* CConfigSchemaHelper::getNewInstance(const char* pDefaultDirOverride)
+{
+    if (CConfigSchemaHelper::s_pCConfigSchemaHelper != NULL)
+    {
+        delete CConfigSchemaHelper::s_pCConfigSchemaHelper;
+        CConfigSchemaHelper::s_pCConfigSchemaHelper = NULL;
+    }
+
+    CConfigSchemaHelper::getInstance(pDefaultDirOverride);
+    CConfigSchemaHelper::getInstance()->populateSchema();
+
+    return CConfigSchemaHelper::getInstance();
+}

+ 192 - 0
configuration/configurator/ConfigSchemaHelper.hpp

@@ -0,0 +1,192 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _CONFIG_SCHEMA_HELPER_HPP_
+#define _CONFIG_SCHEMA_HELPER_HPP_
+
+#include "jiface.hpp"
+#include "jptree.hpp"
+#include "jutil.hpp"
+#include "jarray.hpp"
+#include "jhash.hpp"
+#include "SchemaAttributes.hpp"
+#include "SchemaAttributeGroup.hpp"
+#include "SchemaElement.hpp"
+#include "SchemaSchema.hpp"
+#include "SchemaExtension.hpp"
+#include "BuildSet.hpp"
+#include "ConfiguratorAPI.hpp"
+#include "SchemaMapManager.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CSchemaMapManager;
+class CSimpleType;
+
+class CConfigSchemaHelper : public ::CInterface
+{
+public:
+
+    IMPLEMENT_IINTERFACE
+
+    static CConfigSchemaHelper* getInstance(const char* pDefaultDirOverride =  NULL);
+    static CConfigSchemaHelper* getInstance(const char* pBuildSetFileName, const char *pBaseDirectory, const char *pDefaultDirOverride = NULL);
+    static CConfigSchemaHelper* getNewInstance(const char* pDefaultDirOverride =  NULL);
+
+    virtual ~CConfigSchemaHelper();
+
+    bool populateSchema();
+    void printConfigSchema(StringBuffer &str) const;
+
+    CSchemaMapManager* getSchemaMapManager()
+    {
+        return m_pSchemaMapManager;
+    }
+
+    void addExtensionToBeProcessed(CExtension *pExtension);
+    void processExtensionArr();
+
+    void addAttributeGroupToBeProcessed(CAttributeGroup *pAttributeGroup);
+    void processAttributeGroupArr();
+
+    void addNodeForBaseProcessing(CXSDNodeWithBase *pNode);
+    void processNodeWithBaseArr();
+
+    void addNodeForTypeProcessing(CXSDNodeWithType *pNode);
+    void processNodeWithTypeArr(CXSDNodeBase *pParentNode = NULL);
+
+    void addElementForRefProcessing(CElement *pElement);
+    void processElementArr(CElement *pElement);
+
+    void addKeyRefForReverseAssociation(const CKeyRef *pKeyRef) const;
+    void processKeyRefReverseAssociation() const;
+
+    void addKeyForReverseAssociation(const CKey *pKeyRef) const;
+    void processKeyReverseAssociation() const;
+
+    bool getXMLFromSchema(StringBuffer& strXML, const char* pXSD); //test purposes
+    void populateEnvXPath();
+    void loadEnvFromConfig(const char *pEnvFile);
+    const char* printDocumentation(const char* comp);
+    void printJSON(const char* comp, char **pOutput, int nIdx = -1, bool bCleanUp = false) const;
+    void printJSONByKey(const char* key, char **pOutput, bool bCleanUp = false) const;
+    void printNavigatorJSON(char **pOutput, bool bCleanUp = false) const;
+    void printDump(const char* comp) const;
+    void dumpStdOut() const;
+    void addToolTip(const char *js);
+    const char* getToolTipJS() const;
+
+    const char* getBasePath() const
+    {
+        return m_pBasePath;
+    }
+
+    void setBasePath(const char *pBasePath);
+    void setEnvTreeProp(const char *pXPath, const char* pValue);
+    const char* getTableValue(const char* pXPath, int nRow = 1) const;
+
+    int getEnvironmentXPathSize() const
+    {
+        return m_strArrayEnvXPaths.length();
+    }
+    const char* getEnvironmentXPaths(int idx) const
+    {
+        assert(idx >= 0);
+        assert(m_strArrayEnvXPaths.length() > idx);
+        return m_strArrayEnvXPaths.item(idx);
+    }
+
+    const char* getAttributeXSDXPathFromEnvXPath(const char* pEnvXPath) const;
+    const char* getElementArrayXSDXPathFromEnvXPath(const char* pXSDXPath) const;
+    int getElementArraySize(const char *pXPath) const;
+    void appendAttributeXPath(const char *pXPath);
+    void appendElementXPath(const char *pXPath);
+
+    static int stripXPathIndex(StringBuffer &strXPath);
+    static bool isXPathTailAttribute(const StringBuffer &strXPath);
+
+    ::IPropertyTree* getEnvPropertyTree()
+    {
+        return m_pEnvPropertyTree;
+    }
+    const ::IPropertyTree* getConstEnvPropertyTree() const
+    {
+        return m_pEnvPropertyTree;
+    }
+    int getNumberOfTables() const
+    {
+        return m_nTables;
+    }
+    void incTables()
+    {
+        m_nTables++;
+    }
+    void resetTables() const
+    {
+        m_nTables = 0;
+    }
+    bool saveConfigurationFile() const;
+    bool saveConfigurationFileAs(const char *pFilePath = NULL);
+
+    const char* getEnvFilePath() const
+    {
+        return m_strEnvFilePath.str();
+    }
+
+    int getInstancesOfComponentType(const char *pCompType) const;
+
+    const char* getInstanceNameOfComponentType(const char *pCompType, int idx);
+
+protected:
+
+    CConfigSchemaHelper(const char* pBuildSetFile = DEFAULT_BUILD_SET_XML_FILE, const char* pBuildSetDir = DEFAULT_BUILD_SET_DIRECTORY, const char* pDefaultDirOverride = NULL);
+
+    CSchemaMapManager *m_pSchemaMapManager;
+    ::CIArrayOf<CExtension> m_extensionArr;
+    ::CIArrayOf<CAttributeGroup> m_attributeGroupArr;
+    ::CIArrayOf<CXSDNodeWithType> m_nodeWithTypeArr;
+    ::CIArrayOf<CXSDNodeWithBase> m_nodeWithBaseArr;
+    ::CIArrayOf<CElement> m_ElementArr;
+    ::CIArrayOf<CKeyRef> m_KeyRefArr;
+    ::StringArray m_strToolTipsJS;
+    ::StringArray m_strArrayEnvXPaths;
+    ::StringArray m_strArrayEnvXMLComponentInstances;
+
+    void setEnvPropertyTree(::IPropertyTree *pEnvTree)
+    {
+        m_pEnvPropertyTree =  pEnvTree;
+    }
+    void setEnvFilePath(const char* pEnvFilePath)
+    {
+        assert(pEnvFilePath != NULL);
+        m_strEnvFilePath.set(pEnvFilePath);
+    }
+
+private:
+
+    static void clearLF(StringBuffer& strToClear);
+
+    static CConfigSchemaHelper* s_pCConfigSchemaHelper;
+    mutable int m_nTables;
+    char *m_pBasePath;
+
+    ::StringBuffer m_strEnvFilePath;
+    ::IPropertyTree *m_pEnvPropertyTree;
+};
+}
+#endif // _CONFIG_SCHEMA_HELPER_HPP_

+ 558 - 0
configuration/configurator/ConfiguratorAPI.cpp

@@ -0,0 +1,558 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "ConfiguratorAPI.hpp"
+#include "ConfiguratorMain.hpp"
+#include "BuildSet.hpp"
+#include "ConfigSchemaHelper.hpp"
+#include "ConfiguratorMain.hpp"
+#include "jstring.hpp"
+#include "SchemaMapManager.hpp"
+#include "SchemaEnumeration.hpp"
+#include "SchemaCommon.hpp"
+#include "ConfiguratorMain.hpp"
+#include "EnvironmentModel.hpp"
+#include "ConfigNotifications.hpp"
+#include <iostream>
+#include "jlog.hpp"
+
+static int nAllocatedTables = 0;
+static  char *modelName[MAX_ARRAY_X];
+
+const char* getTableDataModelName(int index)
+{
+    if (index < nAllocatedTables)
+        return modelName[index];
+    else
+    {
+        modelName[index] = new char[MAX_ARRAY_Y];
+        sprintf(modelName[index],"tableDataModel%d", index);
+
+        nAllocatedTables++;
+        return modelName[index];
+    }
+}
+
+void deleteTableModels()
+{
+    while (nAllocatedTables > 0)
+    {
+        delete[] modelName[nAllocatedTables];
+    }
+}
+
+namespace CONFIGURATOR_API
+{
+    using namespace CONFIGURATOR;
+static CConfigSchemaHelper *s_pConfigSchemaHelper = NULL;
+
+void reload(const char *pFile)
+{
+    assert(pFile != NULL && *pFile != 0);
+    delete s_pConfigSchemaHelper;
+
+    s_pConfigSchemaHelper = NULL;
+    s_pConfigSchemaHelper = CConfigSchemaHelper::getInstance();
+    s_pConfigSchemaHelper->populateSchema();
+
+    CConfigSchemaHelper::getInstance()->loadEnvFromConfig(pFile);
+}
+
+int getNumberOfAvailableComponents()
+{
+    assert(s_pConfigSchemaHelper != NULL);
+    return CBuildSetManager::getInstance()->getBuildSetComponentCount();
+}
+
+int getNumberOfAvailableServices()
+{
+    assert(s_pConfigSchemaHelper != NULL);
+    return  CBuildSetManager::getInstance()->getBuildSetServiceCount();
+}
+
+#ifdef CONFIGURATOR_LIB
+
+int initialize()
+{
+    assert(s_pConfigSchemaHelper == NULL);
+
+    static bool bOnce = true;
+
+    if (bOnce == true)
+    {
+        bOnce = false;
+
+        InitModuleObjects();
+
+    }
+
+    s_pConfigSchemaHelper = CConfigSchemaHelper::getInstance();
+    s_pConfigSchemaHelper->populateSchema();
+
+    return 1;
+}
+
+#else // CONFIGURATOR_LIB
+
+int initialize(int argc, char *argv[])
+{
+    assert(s_pConfigSchemaHelper == NULL);
+    InitModuleObjects();
+
+    s_pConfigSchemaHelper = CConfigSchemaHelper::getInstance();
+
+    return 0;
+}
+
+#endif // CONFIGURATOR_LIB
+
+int getValue(const char *pXPath, char *pValue)
+{
+    // By Default, return xPath as value.
+
+    if (pXPath == NULL || *pXPath == 0)
+        return 0;
+
+    strcpy(pValue, pXPath[0] == '#' ? &(pXPath[1]) : pXPath); // href for frontend
+    CAttribute *pAttribute = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getAttributeFromXPath(pXPath);
+
+    if(pAttribute == NULL)
+        ::std::cout << "xPath: " << pXPath << "| value: " << pXPath << ::std::endl;
+    else if (pAttribute->isInstanceValueValid() == true)
+    {
+        strcpy(pValue, pAttribute->getInstanceValue());
+        ::std::cout << "xPath: " << pXPath << "| value: " << pValue << ::std::endl;
+    }
+
+    return 1;
+}
+
+bool setValue(const char *pXPath, const char *pValue)
+{
+    assert(pXPath != NULL && pXPath[0] != 0);
+    assert(pValue != NULL);
+
+    StringBuffer strXPath(pXPath);
+    strXPath.replace('_','/');
+
+    CAttribute *pAttribute = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getAttributeFromXPath(strXPath.str());
+
+    if (pAttribute == NULL)
+        return false;
+
+    assert(pAttribute != NULL);
+    pAttribute->setEnvValueFromXML(pValue);
+
+    /*if (strstr(pValue, "/") == NULL)
+    {
+        strXPath.replace('_','/');
+    }*/
+
+    CConfigSchemaHelper::getInstance()->setEnvTreeProp(strXPath.str(), pValue);
+
+    return true;
+}
+
+int getIndex(const char *pXPath)
+{
+    CRestriction *pRestriction = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getRestrictionFromXPath(pXPath);
+    assert(pRestriction != NULL);
+    assert(pRestriction->getEnumerationArray() != NULL);
+
+    return pRestriction->getEnumerationArray()->getEnvValueNodeIndex();
+}
+
+void setIndex(const char *pXPath, int newIndex)
+{
+    assert(newIndex >= 0);
+
+    CRestriction *pRestriction = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getRestrictionFromXPath(pXPath);
+
+    assert(pRestriction != NULL);
+    assert(pRestriction->getEnumerationArray() != NULL);
+    pRestriction->getEnumerationArray()->setEnvValueNodeIndex(newIndex);
+
+    CConfigSchemaHelper::getInstance()->setEnvTreeProp(pXPath, pRestriction->getEnumerationArray()->item(newIndex).getValue());
+}
+
+const char* getTableValue(const char *pXPath, int nRow)
+{
+    assert(pXPath != NULL && *pXPath != 0);
+
+    CAttribute *pAttribute = NULL;
+    CElement *pElement = NULL;
+
+    if (CConfigSchemaHelper::isXPathTailAttribute(pXPath) == true)
+       pAttribute = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getAttributeFromXPath(pXPath);
+
+    if (pAttribute == NULL)
+    {
+        pElement =  CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getElementFromXPath(pXPath);
+        assert(pElement != NULL);
+
+        return pAttribute->getInstanceValue();
+    }
+    else
+    {
+        assert(pAttribute != NULL);
+        if (nRow == 1)
+            return pAttribute->getInstanceValue();
+        else
+        {
+            StringBuffer strXPath(pXPath);
+            const StringBuffer strXPathOriginal(pXPath);
+
+            int offset = strXPathOriginal.length() - (CConfigSchemaHelper::stripXPathIndex(strXPath) + 1) ;
+            CConfigSchemaHelper::stripXPathIndex(strXPath);
+
+            strXPath.appendf("[%d]", nRow);
+            strXPath.append(strXPathOriginal, offset, strXPathOriginal.length() - offset);
+            pAttribute =  CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getAttributeFromXPath(strXPath.str());
+
+            if (STRICTNESS_LEVEL >= DEFAULT_STRICTNESS)
+                assert(pAttribute != NULL);
+
+            if (pAttribute == NULL)
+                return NULL;
+
+            return pAttribute->getInstanceValue();
+        }
+    }
+}
+
+void setTableValue(const char *pXPath, int index, const char *pValue)
+{
+    UNIMPLEMENTED;
+}
+
+int getNumberOfUniqueColumns()
+{
+    return CConfigSchemaHelper::getInstance()->getEnvironmentXPathSize();
+}
+
+const char* getColumnName(int idx)
+{
+    if (idx < CConfigSchemaHelper::getInstance()->getEnvironmentXPathSize())
+        return CConfigSchemaHelper::getInstance()->getEnvironmentXPaths(idx);
+    else
+        return NULL;
+}
+
+int getNumberOfRows(const char* pXPath)
+{
+    assert(pXPath != NULL && *pXPath != 0);
+    PROGLOG("Get number of rows for %s = %d", pXPath, CConfigSchemaHelper::getInstance()->getElementArraySize(pXPath));
+
+    return CConfigSchemaHelper::getInstance()->getElementArraySize(pXPath);
+}
+
+int getNumberOfTables()
+{
+    return CConfigSchemaHelper::getInstance()->getNumberOfTables();
+}
+
+const char* getServiceName(int idx, char *pName)
+{
+    if (pName != NULL)
+        strcpy (pName, CBuildSetManager::getInstance()->getBuildSetServiceName(idx));
+
+    return CBuildSetManager::getInstance()->getBuildSetServiceName(idx);
+}
+
+const char* getComponentName(int idx, char *pName)
+{
+    if (pName != NULL)
+        strcpy (pName, CBuildSetManager::getInstance()->getBuildSetComponentTypeName(idx));
+
+    return CBuildSetManager::getInstance()->getBuildSetComponentTypeName(idx);
+}
+
+int openConfigurationFile(const char* pFile)
+{
+    /*s_pConfigSchemaHelper = NULL;
+    s_pConfigSchemaHelper = CConfigSchemaHelper::getInstance();
+
+    StringArray arrXSDS;
+    arrXSDS.append("dali.xsd");
+    CBuildSetManager::getInstance()->setBuildSetArray(arrXSDS);
+    s_pConfigSchemaHelper->populateSchema();*/
+
+    CConfigSchemaHelper::getNewInstance()->loadEnvFromConfig(pFile);
+    return 1;
+}
+
+int getNumberOfComponentsInConfiguration(void *pData)
+{
+    if (pData == NULL)
+    {
+        return CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getNumberOfComponents();
+    }
+    else
+    {
+        CElement *pElement = static_cast<CElement*>(pData);
+        assert(pElement->getNodeType() == XSD_ELEMENT);
+
+        CElementArray *pElementArray = static_cast<CElementArray*>(pElement->getParentNode());
+        assert(pElementArray->getNodeType() == XSD_ELEMENT_ARRAY);
+
+        return pElementArray->length();
+    }
+}
+
+void* getComponentInConfiguration(int idx)
+{
+    assert(idx < CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getNumberOfComponents());
+    return CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getComponent(idx);
+}
+
+void* getComponentInstance(int idx, void *pData)
+{
+    assert(pData != NULL);
+    assert(((static_cast<CElement*>(pData))->getNodeType()) == XSD_ELEMENT);
+
+    CElement *pElement = static_cast<CElement*>(pData);
+    CElementArray *pElementArray = static_cast<CElementArray*>(pElement->getParentNode());
+
+    if (pElementArray->length() >= idx)
+        idx = 0;
+
+    return  &(pElementArray->item(idx));
+}
+
+const char* getComponentNameInConfiguration(int idx, void *pData)
+{
+    if (pData == NULL)
+        return CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getComponent(idx)->getName();
+
+    assert(!"Invalid component index");
+    return NULL;
+}
+
+
+const void* getPointerToComponentInConfiguration(int idx, void *pData, int compIdx)
+{
+    if (pData == NULL)
+    {
+        const CElement *pElement = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getComponent(idx);
+        assert(pElement != NULL);
+
+        const CXSDNodeBase *pNodeBase = pElement->getConstParentNode();
+        const CElementArray *pElementArray = dynamic_cast<const CElementArray*>(pNodeBase);
+        assert(pElementArray != NULL);
+
+        return pElementArray;
+    }
+    else
+    {
+        assert( compIdx >= 0);
+        CElementArray *pElementArray = static_cast<CElementArray*>(pData);
+        assert(pElementArray->getNodeType() == XSD_ELEMENT_ARRAY);
+
+        const CXSDNodeBase *pNodeBase = &(pElementArray->item(compIdx+idx));
+        return(dynamic_cast<const CElement*>(pNodeBase));
+    }
+}
+
+const void* getPointerToComponentTypeInConfiguration(void *pData)
+{
+    assert (pData != NULL);
+    CElement *pElement = static_cast<CElement*>(pData);
+    assert (pElement->getNodeType() == XSD_ELEMENT);
+
+    CElementArray *pElementArray = static_cast<CElementArray*>(pElement->getParentNode());
+
+    return &(pElementArray->item(0));
+}
+
+int getIndexOfParent(void *pData)
+{
+    assert (pData != NULL);
+    assert((static_cast<CElement*>(pData))->getNodeType() == XSD_ELEMENT);
+
+    int nIndexOfParent = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getIndexOfElement(static_cast<CElement*>(pData));
+    assert(nIndexOfParent >= 0);
+
+    return nIndexOfParent;
+}
+
+const void* getPointerToComponents()
+{
+    assert(CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getComponent(0)->getConstParentNode()->getNodeType() == XSD_ELEMENT_ARRAY);
+    return (CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getComponent(0)->getConstParentNode());
+}
+
+int getNumberOfChildren(void *pData)
+{
+    int nRetVal = 0;
+
+    if (pData == NULL)
+    {
+        assert(!"Should not be null"); // why ever null?
+        return 0;
+    }
+
+    if (pData == (void*)(CEnvironmentModel::getInstance()))
+        nRetVal = (static_cast<CEnvironmentModel*>(pData))->getNumberOfRootNodes();
+    else // must be of type CEnvironmentModelNode*
+    {
+        CEnvironmentModelNode *pNode = static_cast<CEnvironmentModelNode*>(pData);
+        nRetVal = pNode->getNumberOfChildren();
+    }
+    return nRetVal;
+}
+
+const char* getData(void *pData)
+{
+    if (pData == NULL)
+        return NULL;
+
+    return CEnvironmentModel::getInstance()->getData(static_cast<CEnvironmentModelNode*>(pData));
+}
+
+const char* getName(void *pData)
+{
+    if (pData == NULL)
+        return NULL;
+
+    return CEnvironmentModel::getInstance()->getInstanceName(static_cast<CEnvironmentModelNode*>(pData));
+}
+
+const char* getFileName(void *pData)
+{
+    if (pData == NULL)
+        return NULL;
+
+    return CEnvironmentModel::getInstance()->getXSDFileName(static_cast<CEnvironmentModelNode*>(pData));
+}
+
+void* getParent(void *pData)
+{
+    if (pData == NULL)
+        return NULL;
+
+    if (pData == (void*)(CEnvironmentModel::getInstance()->getRoot()))
+       return (void*)(CEnvironmentModel::getInstance());
+    else
+       return (void*)(CEnvironmentModel::getInstance()->getParent(static_cast<CEnvironmentModelNode*>(pData)));
+    }
+
+void* getChild(void *pData, int idx)
+{
+    if (pData == NULL || pData == CEnvironmentModel::getInstance())
+    {
+        if (idx == 0)
+            return (void*)(CEnvironmentModel::getInstance()->getRoot(0));
+        return NULL;
+    }
+    else
+        return (void*)(CEnvironmentModel::getInstance()->getChild(static_cast<CEnvironmentModelNode*>(pData), idx));
+}
+
+int getIndexFromParent(void *pData)
+{
+    CEnvironmentModelNode *pNode = static_cast<CEnvironmentModelNode*>(pData);
+
+    if (pNode->getParent() == NULL)
+        return 0; // Must be 'Environment' node
+
+    const CEnvironmentModelNode *pGrandParent = pNode->getParent();
+
+    int nChildren = pGrandParent->getNumberOfChildren();
+
+    for (int idx = 0; idx < nChildren; idx++)
+    {
+        if (pNode == pGrandParent->getChild(idx))
+            return idx;
+    }
+
+    assert(!"Should not reach here");
+    return 0;
+}
+
+void* getRootNode(int idx)
+{
+    return (void*)(CEnvironmentModel::getInstance()->getRoot(idx));
+}
+
+void* getModel()
+{
+    return (void*)(CEnvironmentModel::getInstance());
+}
+
+void getJSON(void *pData, char **pOutput, int nIdx)
+{
+    CConfigSchemaHelper::getInstance()->printJSON(CONFIGURATOR_API::getFileName(pData), pOutput, nIdx, true);
+}
+
+void getNavigatorJSON(char **pOutput)
+{
+    CConfigSchemaHelper::getInstance()->printNavigatorJSON(pOutput, true);
+}
+
+void getJSONByComponentName(const char *pComponentName, char **pOutput, int nIdx)
+{
+    CConfigSchemaHelper::getInstance()->printJSON(pComponentName, pOutput, nIdx, true);
+}
+
+void getJSONByComponentKey(const char *pKey, char **pOutput)
+{
+    CConfigSchemaHelper::getInstance()->printJSONByKey(pKey, pOutput, true);
+}
+
+const char* getDocBookByIndex(int idx)
+{
+    const char *pFileName = CBuildSetManager::getInstance()->getBuildSetComponentFileName(idx);
+    return CConfigSchemaHelper::getInstance()->printDocumentation(pFileName);
+}
+
+bool saveConfigurationFile()
+{
+    return CConfigSchemaHelper::getInstance()->saveConfigurationFile();
+}
+
+bool saveConfigurationFileAs(const char *pFilePath)
+{
+    if (pFilePath == NULL || *pFilePath == 0)
+        return false;
+
+    return CConfigSchemaHelper::getInstance()->saveConfigurationFileAs(pFilePath);
+}
+
+int getNumberOfNotificationTypes()
+{
+    return CNotificationManager::getInstance()->getNumberOfNotificationTypes();
+}
+
+const char* getNotificationTypeName(int type)
+{
+    return CNotificationManager::getInstance()->getNotificationTypeName(type);
+}
+
+int getNumberOfNotifications(int type)
+{
+    enum ENotificationType eType = static_cast<ENotificationType>(type);
+    return CNotificationManager::getInstance()->getNumberOfNotifications(eType);
+}
+
+const char* getNotification(int type, int idx)
+{
+    const char *pRet = NULL;
+    enum ENotificationType eType = static_cast<ENotificationType>(type);
+
+    return CNotificationManager::getInstance()->getNotification(eType, idx);
+}
+} // CONFIGURATOR_API namespace

+ 80 - 0
configuration/configurator/ConfiguratorAPI.hpp

@@ -0,0 +1,80 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _CONFIGURATOR_API_HPP_
+#define _CONFIGURATOR_API_HPP_
+
+#define MAX_ARRAY_X 100
+#define MAX_ARRAY_Y 128
+
+const char* getTableDataModelName(int index);
+void deleteTableModels();
+
+
+namespace CONFIGURATOR_API
+{
+//#ifdef CONFIGURATOR_LIB
+    extern "C" int initialize();
+//#endif // CONFIGURATOR_LIB
+
+extern "C" int getNumberOfAvailableComponents();
+extern "C" int getNumberOfAvailableServices();
+extern "C" const char* getServiceName(int idx, char *pName = 0);
+extern "C" const char* getComponentName(int idx, char *pName = 0);
+extern "C" int getValue(const char *pXPath, char *pValue);
+extern "C" bool setValue(const char *pXPath, const char *pValue);
+extern "C" int getIndex(const char *pXPath);
+extern "C" void setIndex(const char *pXPath, int newIndex);
+extern "C" const char* getTableValue(const char *pXPath, int nRow);
+extern "C" void setTableValue(const char *pXPath, int index, const char *pValue);
+extern "C" int getNumberOfUniqueColumns();
+extern "C" const char* getColumnName(int idx);
+extern "C" int getNumberOfRows(const char* pXPath);
+extern "C" int getNumberOfTables();
+extern "C" int openConfigurationFile(const char* pFile);
+extern "C" int getNumberOfComponentsInConfiguration(void *pData);
+extern "C" void* getComponentInConfiguration(int idx);
+extern "C" void* getComponentInstance(int idx, void *pData);
+extern "C" const void* getPointerToComponentTypeInConfiguration(void *pData);
+extern "C" const char* getComponentNameInConfiguration(int idx, void *pData);
+extern "C" const void* getPointerToComponentInConfiguration(int idx, void *pData, int compIdx = -1);
+extern "C" const void* getPointerToComponents();
+extern "C" int getIndexOfParent(void *pData);
+extern "C" int getNumberOfChildren(void *pData);
+extern "C" const char* getData(void *pData);
+extern "C" const char* getName(void *pData);
+extern "C" const char* getFileName(void *pData);
+extern "C" void* getParent(void *pData);
+extern "C" void* getChild(void *pData, int idx);
+extern "C" int getIndexFromParent(void *pData);
+extern "C" void* getRootNode(int idx = 0);
+extern "C" void* getModel();
+extern "C" void reload(const char *pFile);
+extern "C" void getJSON(void *pData, char **pOutput, int nIdx);
+extern "C" void getNavigatorJSON(char **pOutput);
+extern "C" void getJSONByComponentName(const char *pComponentName, char **pOutput, int nIdx);
+extern "C" void getJSONByComponentKey(const char *pKey, char **pOutput);
+extern "C" const char* getDocBookByIndex(int idx);
+extern "C" bool saveConfigurationFile();
+extern "C" bool saveConfigurationFileAs(const char *pFilePath);
+extern "C" int getNumberOfNotificationTypes();
+extern "C" const char* getNotificationTypeName(int type);
+extern "C" int getNumberOfNotifications(int type);
+extern "C" const char* getNotification(int type, int idx);
+}
+
+#endif // _CONFIGURATOR_API_HPP_

+ 352 - 0
configuration/configurator/ConfiguratorMain.cpp

@@ -0,0 +1,352 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "ConfiguratorMain.hpp"
+#include "EnvironmentConfiguration.hpp"
+#include "WizardBase.hpp"
+#include "ConfigSchemaHelper.hpp"
+#include "SchemaCommon.hpp"
+#include "ExceptionStrings.hpp"
+#include <iostream>
+#include "jfile.hpp"
+#include "jstring.hpp"
+
+#define BUFF_SIZE 1024
+
+using namespace CONFIGURATOR;
+const char *pDefaultDocExt =  ".mod.xml";
+const char *pDefaultJSONExt =  ".json";
+
+void usage()
+{
+    ::std::cout << "configurator -use <xsd files>  -b <base dir path>" << ::std::endl;
+    ::std::cout << "Example Usage: ./configurator -use dali.xsd -b /opt/HPCCSystems/componentfiles/configxml -d -t /tmp " << ::std::endl;
+    ::std::cout << "-d -doc                           : generate docs" << ::std::endl;
+    ::std::cout << "-b -base <base dir path>          : base directory path to use with -use option and for xs:include references in xsd files" << ::std::endl;
+    ::std::cout << "-t -target <target directory>     : directory to which to docs will be written. If not specified, then output will go to ::std::out" << ::std::endl;
+    ::std::cout << "-u -use <schema xsd>              : use specified xsd schema instead of buildset file" << ::std::endl;
+    ::std::cout << "-h -help                          : prints out this usage" << ::std::endl;
+
+    ::std::cout << ::std::endl;
+
+    ::std::cout << ::std::endl << "** Experimental **" << ::std::endl;
+    ::std::cout <<"Example Usage: ./configurator -use esp.xsd -b /opt/HPCCSystems/componentfiles/configxml/ -doc" << ::std::endl;
+    ::std::cout << "-f -file <build set file>         : buildset file name (required if base directory is specfied" << ::std::endl;
+    ::std::cout << "-p -path <base dir path>          : base directory path (required if buildset file name is specified)" << ::std::endl;
+    ::std::cout << "-x -xsd  <xsd file name>          : xsd file name (can be more than one) - For use with buildset file" << ::std::endl;
+    ::std::cout << "-l -list                          : list available xsd files" << ::std::endl;
+    ::std::cout << "-m -xml                           : generate XML configuration file" << ::std::endl;
+    ::std::cout << "-j -json <component key>          : prints JSON" << ::std::endl;
+    ::std::cout << "-c -env -config <path to env xml file> : load environment config xml file (e.g. environment.xml) " << ::std::endl;
+    ::std::cout << "-dump                             : dump out xsd internal structure and values" << ::std::endl;
+}
+
+#ifndef CONFIGURATOR_LIB
+    int main(int argc, char *argv[])
+#else
+    int ConfiguratorMain(int argc, char* argv[])
+#endif // CONFIGURATOR_LIB
+{
+    InitModuleObjects();
+
+    int idx = 1;
+
+    CConfigSchemaHelper *pSchemaHelper = NULL;
+
+    char pBuildSetFile[BUFF_SIZE];
+    char pBuildSetFileDir[BUFF_SIZE];
+    char pTargetDocDir[BUFF_SIZE];
+    char pTargetDocExt[BUFF_SIZE];
+    char pOverrideSchema[BUFF_SIZE];
+    char pBasePath[BUFF_SIZE];
+    char pEnvXMLPath[BUFF_SIZE];
+    StringBuffer strJSONFile;
+    StringBuffer strComponentKey;
+
+    memset(pBuildSetFile, 0, sizeof(pBuildSetFile));
+    memset(pBuildSetFileDir, 0, sizeof(pBuildSetFileDir));
+    memset(pTargetDocDir, 0, sizeof(pTargetDocDir));
+    memset(pOverrideSchema, 0, sizeof(pOverrideSchema));
+    memset(pBasePath, 0, sizeof(pBasePath));
+    memset(pEnvXMLPath, 0, sizeof(pEnvXMLPath));
+
+    strncpy(pTargetDocExt, pDefaultDocExt, sizeof(pTargetDocExt));
+
+    bool bListXSDs      = false;
+    bool bGenDocs       = false;
+	bool bGenJSON       = false;
+    bool bDump          = false;
+    bool bLoadEnvXML    = false;
+
+    StringArray arrXSDs;
+
+    if (argc == 1)
+    {
+        usage();
+        return 0;
+    }
+
+    while(idx < argc)
+    {
+        if (stricmp(argv[idx], "-help") == 0 || stricmp(argv[idx], "-h") == 0)
+        {
+            usage();
+            return 0;
+        }
+        if (stricmp(argv[idx], "-dump") == 0)
+            bDump = true;
+        if (stricmp(argv[idx], "-config") == 0 || stricmp(argv[idx], "-c") == 0 || stricmp(argv[idx], "-env") == 0)
+        {
+            idx++;
+            bLoadEnvXML = true;
+
+            if (argv[idx] == NULL)
+            {
+                ::std::cout << "Missing env xml file parameter!" << ::std::endl;
+                return 0;
+            }
+            strncpy(pEnvXMLPath, argv[idx], BUFF_SIZE);
+        }
+        else if (stricmp(argv[idx], "-file") == 0 || stricmp(argv[idx], "-f") == 0)
+        {
+            idx++;
+
+            assert(argv[idx]);
+            if (argv[idx] == NULL)
+            {
+                ::std::cout << "Missing file parameter!" << ::std::endl;
+                return 0;
+            }
+            strncpy(pBuildSetFile, argv[idx], BUFF_SIZE);
+        }
+        else if (stricmp(argv[idx], "-path") == 0 || stricmp(argv[idx], "-p") == 0)
+        {
+            idx++;
+
+            assert(argv[idx]);
+            if (argv[idx] == NULL)
+            {
+                ::std::cout << "Missing path parameter!" << ::std::endl;
+                return 0;
+            }
+            strncpy(pBuildSetFileDir, argv[idx], BUFF_SIZE);
+        }
+        else if (stricmp(argv[idx], "-base") == 0 || stricmp(argv[idx], "-b") == 0)
+        {
+            idx++;
+
+            assert(argv[idx]);
+            if (argv[idx] == NULL)
+            {
+                ::std::cout << "Missing base dir parameter!" << ::std::endl;
+                return 0;
+            }
+            strncpy(pBasePath, argv[idx], BUFF_SIZE);
+        }
+        else if (stricmp(argv[idx], "-xsd") == 0 || stricmp(argv[idx], "-x") == 0)
+        {
+            idx++;
+
+            assert(argv[idx]);
+            if (argv[idx] == NULL)
+            {
+                ::std::cout << "Missing XSD file!" << ::std::endl;
+                return 0;
+            }
+            arrXSDs.append(argv[idx]);
+        }
+        else if (stricmp(argv[idx], "-list") == 0 || stricmp(argv[idx], "-l") == 0)
+            bListXSDs = true;
+        else if (stricmp(argv[idx], "-doc") == 0 || stricmp(argv[idx], "-d") == 0)
+            bGenDocs = true;
+        else if (stricmp(argv[idx], "-target") == 0 || stricmp(argv[idx], "-t") == 0)
+        {
+            idx++;
+
+            assert(argv[idx]);
+            if (argv[idx] == NULL)
+            {
+                ::std::cout << "Missing target!" << ::std::endl;
+                return 0;
+            }
+            strcpy(pTargetDocDir,argv[idx]);
+        }
+        else if (stricmp(argv[idx], "-extension") == 0 || stricmp(argv[idx], "-e") == 0)
+        {
+            idx++;
+
+            assert(argv[idx]);
+            if (argv[idx] == NULL)
+            {
+                ::std::cout << "Missing extension!" << ::std::endl;
+                return 0;
+            }
+            if (argv[idx][0] != '.')
+            {
+                strcat(pTargetDocExt, ".");
+                strcpy(&(pTargetDocExt[1]),argv[idx]);
+            }
+            else if (*pTargetDocExt == 0)
+                strcat(pTargetDocExt, "");
+            else
+                strcpy(pTargetDocExt,argv[idx]);
+        }
+        else if (stricmp(argv[idx], "-use") == 0 || stricmp(argv[idx], "-u") == 0)
+        {
+            idx++;
+
+            assert(argv[idx]);
+            if (argv[idx] == NULL)
+            {
+                ::std::cout << "Missing schema xsd!" << ::std::endl;
+                return 0;
+            }
+            else
+            {
+                strcpy(pOverrideSchema, argv[idx]);
+                arrXSDs.append(argv[idx]);
+            }
+        }
+        else if (stricmp(argv[idx], "-json") == 0 || stricmp(argv[idx], "-j") == 0)
+        {
+            bGenJSON = true;
+            idx++;
+            strComponentKey.set(argv[idx]);
+        }
+        idx++;
+    }
+
+    if ((pBuildSetFile[0] != 0) ^ (pBuildSetFileDir[0] != 0))
+    {
+        puts("-file and -path need to be both set or neither one!");
+        return 0;
+    }
+    if (bGenDocs == true && arrXSDs.length() == 0)
+    {
+        puts("No XSDs specified for doc generation!");
+        return 0;
+    }
+    if (pBuildSetFile[0] == 0 && pOverrideSchema[0] == 0)
+    {
+        pSchemaHelper = CConfigSchemaHelper::getInstance();
+    }
+    else if (pBuildSetFile[0] == 0)
+    {
+        pSchemaHelper = CConfigSchemaHelper::getInstance(pBasePath);
+    }
+    else
+    {
+        pSchemaHelper = CConfigSchemaHelper::getInstance(pBuildSetFile, pBuildSetFileDir);
+    }
+
+    assert(pSchemaHelper);
+    if (pOverrideSchema[0] != 0)
+        CBuildSetManager::getInstance()->setBuildSetArray(arrXSDs);
+
+    try
+    {
+        pSchemaHelper->populateSchema();
+    }
+    CATCH_EXCEPTION_AND_EXIT
+
+    if (bListXSDs == true)
+    {
+        StringArray arrXSDs;
+        CBuildSetManager::getInstance()->getBuildSetComponents(arrXSDs);
+
+        if (arrXSDs.length() > 0)
+            ::std::cout << "XSD files (" << arrXSDs.length() << ")" << ::std::endl;
+
+        for (int idx = 0; idx < arrXSDs.length(); idx++)
+            ::std::cout << "(" << idx+1 << ") " << arrXSDs.item(idx) << ::std::endl;
+    }
+
+    for (int idx =  0; bGenDocs == true && idx < arrXSDs.length(); idx++)
+    {
+        if (pTargetDocDir[0] == 0)
+            ::std::cout << pSchemaHelper->printDocumentation(arrXSDs.item(idx));
+        else
+        {
+            Owned<IFile>   pFile;
+            Owned<IFileIO> pFileIO;
+            StringBuffer strTargetPath;
+            const char *pXSDFile = strrchr(arrXSDs.item(idx), '/') == NULL ? arrXSDs.item(idx) : strrchr(arrXSDs.item(idx),'/');
+
+            strTargetPath.append(pTargetDocDir).append("/").append(pXSDFile).append(pTargetDocExt);
+            pFile.setown(createIFile(strTargetPath.str()));
+            pFileIO.setown(pFile->open(IFOcreaterw));
+
+            const char *pDoc = pSchemaHelper->printDocumentation(arrXSDs.item(idx));
+
+            if (pDoc == NULL)
+                continue;
+
+            pFileIO->write(0, strlen(pDoc), pDoc);
+        }
+    }
+    for (int idx =  0; bGenJSON == true && idx < arrXSDs.length(); idx++)
+    {
+        if (bLoadEnvXML == true)
+            pSchemaHelper->loadEnvFromConfig(pEnvXMLPath);
+
+        if (pTargetDocDir[0] == 0)
+        {
+            char *pOutput = NULL;
+
+            //pSchemaHelper->printJSONByKey(/*arrXSDs.item(idx)*/"DaliServerProcess[2]", &pOutput);
+            //pSchemaHelper->printJSONByKey(strComponentKey.str(), &pOutput);
+            pSchemaHelper->printJSON(strComponentKey.str(), &pOutput);
+            ::std::cout << pOutput;
+
+            free(pOutput);
+        }
+        else
+        {
+            Owned<IFile>   pFile;
+            Owned<IFileIO> pFileIO;
+            StringBuffer strTargetPath;
+
+            const char *pXSDFile = strrchr(arrXSDs.item(idx), '/') == NULL ? arrXSDs.item(idx) : strrchr(arrXSDs.item(idx),'/');
+
+            strTargetPath.append(pTargetDocDir).append("/").append(pXSDFile).append(pDefaultJSONExt);
+            pFile.setown(createIFile(strTargetPath.str()));
+            pFileIO.setown(pFile->open(IFOcreaterw));
+
+            char *pJSON = NULL;
+            //pSchemaHelper->printJSON(arrXSDs.item(idx), &pJSON);
+            //pSchemaHelper->printJSONByKey(/*arrXSDs.item(idx)*/"#DaliServerProcess[2]", &pJSON);
+            pSchemaHelper->printJSONByKey(strComponentKey.str(), &pJSON);
+
+            if (pJSON == NULL)
+            {
+                free(pJSON);
+                continue;
+            }
+            pFileIO->write(0, strlen(pJSON), pJSON);
+            free(pJSON);
+        }
+    }
+
+    for (int idx =  0; (bDump == true || bLoadEnvXML == true) && idx < arrXSDs.length(); idx++)
+    {
+        if (bLoadEnvXML == true)
+            pSchemaHelper->loadEnvFromConfig(pEnvXMLPath);
+        if (bDump == true)
+            pSchemaHelper->printDump(arrXSDs.item(idx));
+    }
+    return 0;
+}

+ 26 - 0
configuration/configurator/ConfiguratorMain.hpp

@@ -0,0 +1,26 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _CONFIGURATOR_MAIN_HPP_
+#define _CONFIGURATOR_MAIN_HPP_
+
+#include "ConfiguratorAPI.hpp"
+void usage();
+#ifdef CONFIGURATOR_LIB
+    extern "C" int ConfiguratorMain(int argc, char* argv[]);
+#endif // CONFIGURATOR_LIB
+#endif // _CONFIGURATOR_MAIN_HPP_

+ 52 - 0
configuration/configurator/DocumentationMarkup.hpp

@@ -0,0 +1,52 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _DOCUMENTATION_MARKUP_HPP
+#define _DOCUMENTATION_MARKUP_HPP
+
+static const char* DM_SECT2 = "sect2";
+static const char* DM_SECT2_END = "</sect2>\n";
+static const char* DM_SECT3_BEGIN = "";
+static const char* DM_SECT3_END = "";
+static const char* DM_SECT4_BEGIN = "";
+static const char* DM_SECT4_END = "";
+static const char* DM_ID = "id";
+static const char* DM_PARA = "para";
+static const char* DM_PARA_BEGIN = "<para><emphasis role=\"bold\">";
+static const char* DM_PARA_END = "</emphasis></para>\n";
+static const char* DM_LINE_BREAK = "<?linebreak?>";
+static const char* DM_LINE_BREAK2 = "_<?linebreak?>";
+static const char* DM_TITLE_BEGIN = DM_PARA_BEGIN;
+static const char* DM_TITLE_END = DM_PARA_END;
+static const char* DM_TITLE_LITERAL = "title";
+static const char* DM_TABLE_BEGIN = "<informaltable colsep=\"1\" rowsep=\"1\" ";
+static const char* DM_TABLE_ID_BEGIN = "id=\"";
+static const char* DM_TABLE_ID_UNDEFINED = "UNDEFINED";
+static const char* DM_TABLE_ID_END = "\">\n";
+static const char* DM_TABLE_END = "</informaltable>\n";
+static const char* DM_TABLE_ROW = "row";
+static const char* DM_TABLE_ENTRY = "entry";
+static const char* DM_TGROUP = "tgroup";
+static const char* DM_TGROUP4_BEGIN = "<tgroup cols=\"4\" align=\"left\">\n";
+static const char* DM_TGROUP4_END = "</tgroup>\n";
+static const char* DM_TGROUP_END = "</tgroup>\n";
+static const char* DM_TBODY_BEGIN = "<thead><row>\n<entry>attribute</entry>\n<entry>values</entry>\n<entry>default</entry>\n<entry>required</entry>\n</row>\n</thead><tbody>\n";
+static const char* DM_TBODY_END = "</tbody>\n";
+static const char* DM_COL_SPEC4  = "<colspec colwidth=\"155pt\" /><colspec colwidth=\"2*\" /><colspec colwidth=\"1*\" /><colspec colwidth=\"0.5*\" />\n";
+static const char* DM_HEADING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE sect1 PUBLIC \"-//OASIS//DTD DocBook XML V4.5//EN\"\n\"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd\">\n";
+
+#endif // _DOCUMENTATION_MARKUP_HPP

+ 80 - 0
configuration/configurator/EnvironmentConfiguration.cpp

@@ -0,0 +1,80 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "EnvironmentConfiguration.hpp"
+#include "XMLTags.h"
+
+using namespace CONFIGURATOR;
+
+CEnvironmentConfiguration* CEnvironmentConfiguration::getInstance()
+{
+    static Owned<CEnvironmentConfiguration> s_ConfigurationSingleton;
+    static CSingletonLock slock;
+
+    if (slock.lock() == true)
+    {
+      if (s_ConfigurationSingleton.get() == NULL)
+      {
+        s_ConfigurationSingleton.setown(new CEnvironmentConfiguration());
+      }
+
+      slock.unlock();
+    }
+
+    return s_ConfigurationSingleton.get();
+}
+
+CEnvironmentConfiguration::CEnvironmentConfiguration()
+{
+
+}
+
+CEnvironmentConfiguration::~CEnvironmentConfiguration()
+{
+
+}
+
+enum CEnvironmentConfiguration::CEF_ERROR_CODES CEnvironmentConfiguration::generateBaseEnvironmentConfiguration()
+{
+    StringBuffer xpath;
+
+    xpath.clear().appendf("<%s><%s></%s>", XML_HEADER, XML_TAG_ENVIRONMENT, XML_TAG_ENVIRONMENT);
+
+    if (m_pEnv.get() != NULL)
+        m_pEnv.clear();
+
+    m_pEnv.setown(createPTreeFromXMLString(xpath.str()));
+
+    IPropertyTree* pSettings = m_pEnv->addPropTree(XML_TAG_ENVSETTINGS, createPTree());
+
+    return CEnvironmentConfiguration::CF_NO_ERROR;
+}
+
+enum CEnvironmentConfiguration::CEF_ERROR_CODES  CEnvironmentConfiguration::addComponent(const char* pCompType)
+{
+    return CEnvironmentConfiguration::CF_NO_ERROR;
+}
+
+enum CEnvironmentConfiguration::CEF_ERROR_CODES  CEnvironmentConfiguration::removeComponent(const char* pCompType, const char* pCompName)
+{
+    return CEnvironmentConfiguration::CF_NO_ERROR;
+}
+
+enum CEnvironmentConfiguration::CEF_ERROR_CODES  CEnvironmentConfiguration::addESPService(const char* espServiceType)
+{
+    return CEnvironmentConfiguration::CF_NO_ERROR;
+}

+ 55 - 0
configuration/configurator/EnvironmentConfiguration.hpp

@@ -0,0 +1,55 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _ENVIRONMENT_CONFIGURATON_HPP_
+#define _ENVIRONMENT_CONFIGURATON_HPP_
+
+#include "jptree.hpp"
+#include "ConfigFileComponentUtils.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CEnvironmentConfiguration : public CConfigFileComponentUtils
+{
+public:
+
+    IMPLEMENT_IINTERFACE
+
+    enum CEF_ERROR_CODES{ CF_NO_ERROR = 0,
+                          CF_UNKNOWN_COMPONENT,
+                          CF_UNKNOWN_ESP_COMPONENT,
+                          CF_COMPONENT_INSTANCE_NOT_FOUND,
+                          CF_OTHER = 0xFF };
+
+    static CEnvironmentConfiguration* getInstance();
+
+    virtual ~CEnvironmentConfiguration();
+
+    enum CEF_ERROR_CODES generateBaseEnvironmentConfiguration();
+    enum CEF_ERROR_CODES addComponent(const char* pCompType);
+    enum CEF_ERROR_CODES removeComponent(const char* pCompType, const char* pCompName);
+    enum CEF_ERROR_CODES addESPService(const char* espServiceType);
+
+protected:
+
+    CEnvironmentConfiguration();
+    Owned<IPropertyTree> m_pEnv;
+private:
+};
+}
+#endif // _ENVIRONMENT_CONFIGURATON_HPP_

+ 239 - 0
configuration/configurator/EnvironmentModel.cpp

@@ -0,0 +1,239 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jlib.hpp"
+#include "jlog.hpp"
+#include <cassert>
+
+#include "EnvironmentModel.hpp"
+#include "SchemaCommon.hpp"
+#include "ConfigSchemaHelper.hpp"
+#include "SchemaMapManager.hpp"
+#include "SchemaElement.hpp"
+#include "SchemaSchema.hpp"
+
+
+#define LOG_CONSTRUCTOR
+
+using namespace CONFIGURATOR;
+
+CEnvironmentModelNode::CEnvironmentModelNode(const CEnvironmentModelNode *pParent, int index,  CXSDNodeBase *pNode) : m_pParent(NULL), m_pArrChildNodes(NULL)
+{
+    if (pParent == NULL && index == 0)  // if this is the 'Environment' Node
+    {
+        this->m_pXSDNode = NULL;
+        this->m_pArrChildNodes = new PointerArray();  // array of ptrs to each component
+
+        int nComps = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getNumberOfComponents();
+
+        for (int idx = 0; idx < nComps; idx++)
+        {
+            CXSDNodeBase *pNode = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getComponent(idx);
+
+            if (pNode == NULL)
+                continue;
+            assert(pNode != NULL);
+
+            CEnvironmentModelNode *pModelNode = new CEnvironmentModelNode(this, 0, pNode);
+            m_pArrChildNodes->append(pModelNode);
+        }
+    }
+    else if (pParent != NULL && pParent->getParent() == NULL)  // component tier
+    {
+        assert(pParent != NULL);
+        assert(pNode != NULL);
+
+        this->m_pParent = pParent;
+        this->m_pXSDNode = pNode;
+        this->m_pArrChildNodes = new PointerArray();
+
+        assert(m_pXSDNode->getNodeType() == XSD_ELEMENT);
+        assert(m_pXSDNode->getConstParentNode()->getNodeType() == XSD_ELEMENT_ARRAY);
+
+        const CElement *pElement =  static_cast<const CElement*>(m_pXSDNode->getNodeByTypeAndNameDescending(XSD_ELEMENT, NULL));
+        const CElementArray *pElementArray = pElement != NULL ? static_cast<const CElementArray*>(pElement->getParentNode()) : NULL;
+
+        for (int idx = 0; (pElementArray != NULL && idx < pElementArray->length()); idx++)
+        {
+            CEnvironmentModelNode *pModelNode = new CEnvironmentModelNode(this, idx, &(pElementArray->item(idx)));
+            m_pArrChildNodes->append(pModelNode);
+        }
+    }
+    else // instance tier
+    {
+        assert(pParent != NULL);
+        assert(pNode != NULL);
+
+        this->m_pParent = pParent;
+        this->m_pXSDNode = pNode;
+        this->m_pArrChildNodes = new PointerArray();
+    }
+}
+
+const CEnvironmentModelNode* CEnvironmentModelNode::getChild(int index) const
+{
+   assert(m_pArrChildNodes == NULL || m_pArrChildNodes->length() > index);
+
+   if (m_pArrChildNodes != NULL)
+   {
+        CEnvironmentModelNode *pNode = static_cast<CEnvironmentModelNode*>(m_pArrChildNodes->item(index));
+        return pNode;
+   }
+   return NULL;
+}
+
+CEnvironmentModelNode::~CEnvironmentModelNode()
+{
+    delete m_pArrChildNodes;
+}
+
+int CEnvironmentModelNode::getNumberOfChildren() const
+{
+    int nRetVal = 0;
+
+    if (m_pArrChildNodes != NULL)
+        nRetVal = m_pArrChildNodes->length();
+    else if (m_pArrChildNodes == NULL && m_pXSDNode != NULL && m_pParent != (CEnvironmentModel::getInstance()->getRoot()))
+        return 0;
+    else
+    {
+        assert(this->getXSDNode()->getNodeType() == XSD_ELEMENT);
+
+        const CElement *pElement = static_cast<const CElement*>(this->getXSDNode());
+        const CElementArray *pElementArray = static_cast<const CElementArray*>(pElement->getConstParentNode());
+        assert(pElementArray->getNodeType() == XSD_ELEMENT_ARRAY);
+
+        nRetVal = pElementArray->getCountOfSiblingElements(pElement->getXSDXPath());
+    }
+    return nRetVal;
+}
+
+CEnvironmentModel* CEnvironmentModel::getInstance()
+{
+    static CEnvironmentModel *s_pCEnvModel = NULL;
+
+    if (s_pCEnvModel == NULL)
+        s_pCEnvModel = new CEnvironmentModel();
+
+    return s_pCEnvModel;
+}
+
+CEnvironmentModel::CEnvironmentModel()
+{
+    m_pRootNode = new CEnvironmentModelNode(NULL);
+}
+
+CEnvironmentModel::~CEnvironmentModel()
+{
+    delete m_pRootNode;
+}
+
+const CEnvironmentModelNode* CEnvironmentModel::getParent(CEnvironmentModelNode *pChild)
+{
+    if (pChild != NULL)
+        return pChild->getParent();
+
+    assert(false);
+    return NULL;
+}
+
+const CEnvironmentModelNode* CEnvironmentModel::getChild(CEnvironmentModelNode *pParent, int index)
+{
+    assert(index >= 0);
+    assert(pParent != NULL);
+
+    if (pParent == NULL)
+    {
+        return m_pRootNode;
+    }
+
+    assert(pParent->getNumberOfChildren() > index);
+    return pParent->getChild(index);
+}
+
+const char* CEnvironmentModel::getData(const CEnvironmentModelNode *pChild) const
+{
+    assert(pChild != NULL);
+
+    if (pChild == reinterpret_cast<const CEnvironmentModelNode*>(this))
+        return NULL;
+
+    const CElement *pElement = static_cast<const CElement*>(pChild->getXSDNode());
+
+    if (pElement != NULL)
+    {
+        const char *pInstanceName = pElement->getInstanceName();
+
+        if (pChild->getParent() != CEnvironmentModel::getInstance()->getRoot())
+            return pInstanceName;
+        else
+            return pElement->getName();
+    }
+    else
+        return "Environment";
+}
+
+const char* CEnvironmentModel::getXSDFileName(const CEnvironmentModelNode *pChild) const
+{
+    assert(pChild != NULL);
+
+    const CElement *pElement = static_cast<const CElement*>(pChild->getXSDNode());
+
+    if (pElement != NULL && pElement->isTopLevelElement() == true)
+    {
+        const CSchema *pSchema = dynamic_cast<const CSchema*>(pElement->getConstAncestorNode(2));
+
+        if (pSchema == NULL)
+        {
+            assert(false);
+            return NULL;
+        }
+        else
+            return pSchema->getSchemaFileName();
+    }
+    else
+        return NULL;
+}
+
+const char* CEnvironmentModel::getInstanceName(const CEnvironmentModelNode *pChild) const
+{
+    assert(pChild != NULL);
+
+    const CElement *pElement = static_cast<const CElement*>(pChild->getXSDNode());
+
+    if (pElement != NULL && pElement->isTopLevelElement() == true)
+        return pElement->getInstanceName();
+    else
+        return pElement->getName();
+}
+
+
+int CEnvironmentModel::getNumberOfRootNodes() const
+{
+    return 1;
+}
+
+CEnvironmentModelNode* CEnvironmentModel::getRoot(int index)
+{
+    assert(m_pRootNode != 0);
+    assert(index == 0);
+
+    if (index != 0)
+        return NULL;
+    else
+        return m_pRootNode;
+}

+ 78 - 0
configuration/configurator/EnvironmentModel.hpp

@@ -0,0 +1,78 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _ENVIRONMENT_MODEL_HPP_
+#define _ENVIRONMENT_MODEL_HPP_
+
+#include <cassert>
+
+namespace CONFIGURATOR
+{
+
+class CXSDNodeBase;
+
+class CEnvironmentModelNode
+{
+public:
+
+    CEnvironmentModelNode(const CEnvironmentModelNode *pParent = 0, int index = 0, CXSDNodeBase *pNode = 0);
+    virtual ~CEnvironmentModelNode();
+
+    int getNumberOfChildren() const;
+
+    const CXSDNodeBase* getXSDNode() const
+    {
+        return m_pXSDNode;
+    }
+
+    const CEnvironmentModelNode* getParent() const
+    {
+        return m_pParent;
+    }
+
+    const CEnvironmentModelNode* getChild(int index) const;
+
+protected:
+
+    CXSDNodeBase *m_pXSDNode;
+    const CEnvironmentModelNode *m_pParent;
+    ::PointerArray *m_pArrChildNodes;
+} __attribute__((aligned (32)));
+
+class CEnvironmentModel
+{
+public:
+
+    static CEnvironmentModel* getInstance();
+
+    virtual ~CEnvironmentModel();
+
+    const CEnvironmentModelNode* getParent(CEnvironmentModelNode *pChild);
+    const CEnvironmentModelNode* getChild(CEnvironmentModelNode *pParent, int index);
+    int getNumberOfRootNodes() const;
+    CEnvironmentModelNode* getRoot(int index = 0);
+    const char* getData(const CEnvironmentModelNode *pChild) const;
+    const char* getInstanceName(const CEnvironmentModelNode *pChild) const;
+    const char* getXSDFileName(const CEnvironmentModelNode *pChild) const;
+
+protected:
+
+    CEnvironmentModel();
+    CEnvironmentModelNode *m_pRootNode;
+};
+}
+#endif // _ENVIRONMENT_MODEL_HPP_

+ 39 - 0
configuration/configurator/ExceptionStrings.cpp

@@ -0,0 +1,39 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jstring.hpp"
+#include "ExceptionStrings.hpp"
+
+using namespace CONFIGURATOR;
+
+const int nDefaultCode = 99;
+
+::IException *CONFIGURATOR::MakeExceptionFromMap(int code, enum eExceptionCodes eCode, const char* pMsg)
+{
+    static StringBuffer strExceptionMessage;
+    strExceptionMessage.setf("Exception: %s\nPossible Action(s): %s\n",  pExceptionStringArray[eCode-1], pExceptionStringActionArray[eCode-1]);
+
+    if (pMsg != NULL)
+        strExceptionMessage.append("\nAdditonal Infomation: ").append(pMsg);
+
+    return MakeStringException(code, "%s", strExceptionMessage.str());
+}
+
+::IException *CONFIGURATOR::MakeExceptionFromMap(enum eExceptionCodes eCode, const char* pMsg)
+{
+    return ::MakeExceptionFromMap(nDefaultCode, eCode, pMsg);
+}

+ 104 - 0
configuration/configurator/ExceptionStrings.hpp

@@ -0,0 +1,104 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _EXCEPTION_STRINGS_HPP_
+#define _EXCEPTION_STRINGS_HPP_
+
+#include "jexcept.hpp"
+#include <cstring>
+
+enum eExceptionCodes
+{
+    EX_STR_CAN_NOT_OPEN_XSD  = 1,
+    EX_STR_SIMPLE_TYPE_ALREADY_DEFINED,
+    EX_STR_COMPLEX_TYPE_ALREADY_DEFINED,
+    EX_STR_ATTRIBUTE_GROUP_ALREADY_DEFINED,
+    EX_STR_CAN_NOT_PROCESS_ENV_XML,
+    EX_STR_XPATH_DOES_NOT_EXIST_IN_TREE,
+    EX_STR_MISSING_REQUIRED_ATTRIBUTE,
+    EX_STR_MISSING_VALUE_ATTRIBUTE_IN_LENGTH,
+    EX_STR_LENGTH_VALUE_MUST_BE_GREATER_THAN_OR_EQUAL_TO_ZERO,
+    EX_STR_PATTERN_HAS_INVALID_VALUE,
+    EX_STR_WHITE_SPACE_HAS_INVALID_VALUE,
+    EX_STR_MISSING_NAME_ATTRIBUTE,
+    EX_STR_UNKNOWN,
+    EX_STR_LAST_ENTRY
+};
+
+namespace CONFIGURATOR
+{
+#define MAX_EXCEPTION_STRING_LENGTH 2048
+
+#define CATCH_EXCEPTION_AND_EXIT \
+catch (::IException *except) \
+{\
+    StringBuffer strErrMsg;\
+    except->errorMessage(strErrMsg);\
+    ::std::cout << ::std::endl << strErrMsg.str() << ::std::endl << ::std::endl;\
+    exit(-1);\
+}
+
+const char pExceptionStringArray[EX_STR_LAST_ENTRY][MAX_EXCEPTION_STRING_LENGTH] = { /*** ALWAYS ADD TO THE END OF THE ARRAY!!! ***/
+                                                                                     "can not open xsd file", //
+                                                                                     "simple type already defined",
+                                                                                     "complex type already defined",
+                                                                                     "attribute group already defined",
+                                                                                     "can not open/parse environment xml configuration",
+                                                                                     "xpath does not exist in supplied tree",
+                                                                                     "the xml file is missing a required attribute based on the xsd",
+                                                                                     "length type can not have an empty value attribute",
+                                                                                     "length value must be greater than or equal to zero",
+                                                                                     /*** ADD CORRESPONDING ENTRY TO pExceptionStringActionArray ***/
+                                                                                    };
+
+const char pExceptionStringActionArray[EX_STR_LAST_ENTRY*2][MAX_EXCEPTION_STRING_LENGTH] = {  /*** ALWAYS ADD TO THE END OF THE ARRAY!!! ***/
+                                                                                            /* 1 */ "Ensure that input xsd files exist and that it's permissions are set properly",
+                                                                                            /* 2 */ "Multiple xs:simpleType tags with the same name defined in xsd files. Try processing xsd files using -use parameter and only specify 1 xsd file for processing." ,
+                                                                                            /* 3 */ "Multiple xs:complexType tags with the same name defined in xsd files. Try processing xsd files using -use parameter and only specify 1 xsd file for processing.",
+                                                                                            /* 4 */ "Multiple xs:attributeGroup tags with the same name defined in xsd files. Try processing xsd files using -use parameter and only specify 1 xsd file for processing.",
+                                                                                            /* 5 */ "Failed to open/parss specified configuration file.  Verify file exits, permissions are set properly, and the file is valid.",
+                                                                                            /* 6 */ "The XML file may have errors.",
+                                                                                            /* 7 */ "The XML file may have errors.  An attribute marked as required in the XSD is missing in the xml file."
+                                                                                            /* 8 */ "The XSD has an node  xs:restriction type with an xs:length datatype that has not value; value is required",
+                                                                                            /* 9 */ "The XSD has an node xs:length @value is not greater than or equal to 0",
+                                                                                            /* 10 */ "The XSD has an node xs:fractionDigits that has a value that is not greater than or equl to 0",
+                                                                                            /* 11 */ "The XSD has an node xs:minLength value that is not greater than or equl to 0",
+                                                                                            /* 12 */ "The XSD has an node xs:minInclusive that has no value attribute",
+                                                                                            /* 13 */ "The XSD has an node xs:max:Exclusive that has no value attribute",
+                                                                                            /* 14 */ "The XSD has an node xs:max:Inclusive that has no value attribute",
+                                                                                            /* 15 */ "The XSD has a node xs:maxLength @value is not greater than or equal to 0",
+                                                                                            /* 16 */ "The XSD has a node xs:pattern @value is not set",
+                                                                                            /* 17 */ "The XSD has a node xs:totalDigits @value is not greater than or equal to 0",
+                                                                                            /* 17 */ "The XSD has a node xs:whitespace @value is not valid",
+                                                                                            /*** ADD CORRESPONDING ENTRY TO pExceptionStringActionArray ***/
+                                                                                        };
+
+enum eActionArray { EACTION_FRACTION_DIGITS_HAS_BAD_LENGTH = 10,
+                    EACTION_MIN_LENGTH_BAD_LENGTH = 11,
+                    EACTION_MIN_INCLUSIVE_NO_VALUE = 12,
+                    EACTION_MAX_EXCLUSIVE_NO_VALUE = 13,
+                    EACTION_MAX_INCLUSIVE_NO_VALUE = 14,
+                    EACTION_MAX_LENGTH_BAD_LENGTH = 15,
+                    EACTION_PATTERN_MISSING_VALUE = 16,
+                    EACTION_TOTAL_DIGITS_BAD_LENGTH = 17,
+                    EACTION_WHITE_SPACE_BAD_VALUE = 18
+                  };
+
+::IException *MakeExceptionFromMap(int code, enum eExceptionCodes, const char* pMsg = NULL);
+::IException *MakeExceptionFromMap(enum eExceptionCodes, const char* pMsg = NULL);
+}
+#endif // _EXCEPTION_STRINGS_HPP_

+ 159 - 0
configuration/configurator/JSONMarkUp.cpp

@@ -0,0 +1,159 @@
+#include "jstring.hpp"
+#include "SchemaCommon.hpp"
+#include "BuildSet.hpp"
+#include "JSONMarkUp.hpp"
+#include "ConfigSchemaHelper.hpp"
+
+using namespace CONFIGURATOR;
+
+void CJSONMarkUpHelper::markUpString(::StringBuffer &str)
+{
+    //str.replaceString("\"","\\\"");
+    //str.replace("[","\\[");
+    //str.replace("]","/]");
+}
+
+void CJSONMarkUpHelper::createUIContent(::StringBuffer &strJSON, unsigned int &offset, const char *pUIType, const char* pLabel, const char* pKey, \
+                                        const char *pToolTip, const char *pDefaultValue, const char *pValues, const char *pValue)
+{
+    assert(pUIType);
+    offset+= STANDARD_OFFSET_1;
+
+    strJSON.appendf(" %s \"%s\"", JSON_LABEL, pLabel);
+    strJSON.appendf(", %s \"%s\"", JSON_TYPE, pUIType);
+
+    StringBuffer strKey(pKey);
+    strKey.replace('/','_'); // for frontend
+
+    if (strKey[0] == '[') //check for array
+        strJSON.appendf(", %s %s", JSON_KEY, strKey.str());
+    else
+        strJSON.appendf(", %s \"%s\"", JSON_KEY, strKey.str());
+
+    StringBuffer strToolTip;
+    if (pToolTip)
+    {
+        strToolTip.set(pToolTip);
+        strToolTip.replaceString("\"","\'");
+    }
+
+    strJSON.appendf(", %s \"%s\"", JSON_TOOLTIP, strToolTip.str());
+    strJSON.appendf(", %s \"%s\"", JSON_DEFAULT_VALUE, pDefaultValue);
+
+    if (strcmp(pUIType, JSON_TYPE_TABLE) != 0 && strcmp(pUIType, JSON_TYPE_TAB) != 0)
+        strJSON.appendf(", %s %s", JSON_VALUE, pValue);
+    if (strcmp(pUIType, JSON_TYPE_DROP_DOWN) == 0 && pValues && *pValues)
+        strJSON.appendf(", %s [ \"%s\" ]", JSON_VALUES, pValues);
+    else if (strcmp(pUIType, JSON_TYPE_TABLE) == 0 && pValues && *pValues)
+        strJSON.appendf(", %s [ \"%s\" ]", JSON_COLUMN_NAMES_VALUE, pValues);
+}
+
+
+
+/*void CJSONMarkUpHelper::createUIContent(::StringBuffer &strJSON, unsigned int &offset, ::StringBuffer strUIType, ::StringBuffer strLabel, ::StringBuffer strKey, ::StringBuffer strToolTip, ::StringBuffer strDefaultValue,\
+                                        ::StringBuffer strValues, ::StringBuffer strValue)
+{
+    assert(strUIType.length() > 0);
+
+    CJSONMarkUpHelper::markUpString(strUIType);
+    CJSONMarkUpHelper::markUpString(strLabel);
+    CJSONMarkUpHelper::markUpString(strToolTip);
+    CJSONMarkUpHelper::markUpString(strDefaultValue);
+    CJSONMarkUpHelper::markUpString(strValues);
+    CJSONMarkUpHelper::markUpString(strValue);
+
+
+    offset+= STANDARD_OFFSET_1;
+
+    strJSON.appendf(" %s \"%s\"", JSON_LABEL, strLabel.str());
+    strJSON.appendf(", %s \"%s\"", JSON_TYPE, strUIType.str());
+
+    strKey.replace('/','_'); // for frontend
+    strJSON.appendf(", %s \"%s\"", JSON_KEY, strKey.str());
+
+    strJSON.appendf(", %s \"%s\"", JSON_TOOLTIP, strToolTip.str());
+    strJSON.appendf(", %s \"%s\"", JSON_DEFAULT_VALUE, strDefaultValue.str());
+
+    if (strcmp(strUIType.str(), JSON_TYPE_TABLE) != 0 && strcmp(strUIType.str(), JSON_TYPE_TAB) != 0)
+        strJSON.appendf(", %s %s", JSON_VALUE, strValue.str());
+
+    if (strcmp(strUIType.str(), JSON_TYPE_DROP_DOWN) == 0 && strValues.length() > 0)
+        strJSON.appendf(", %s [ \"%s\" ]", JSON_VALUES, strValues.str());
+    else if (strcmp(strUIType.str(), JSON_TYPE_TABLE) == 0 && strValues.length() > 0)
+        strJSON.appendf(", %s [ \"%s\" ]", JSON_COLUMN_NAMES_VALUE, strValues.str());
+}*/
+
+void CJSONMarkUpHelper::getNavigatorJSON(::StringBuffer &strJSON)
+{
+    int nComponents = CBuildSetManager::getInstance()->getBuildSetComponentCount();
+
+    if (nComponents == 0)
+        return;
+
+    strJSON.append(JSON_NAVIGATOR_BEGIN);
+    strJSON.append(JSON_NAVIGATOR_TEXT).append("\"").append(CConfigSchemaHelper::getInstance()->getEnvFilePath()).append("\",").append("\n");
+    strJSON.append(JSON_NAVIGATOR_KEY).append("\"#").append(CConfigSchemaHelper::getInstance()->getEnvFilePath()).append("\",").append("\n");
+
+    for (int i = 0; i < nComponents; i++)
+    {
+        if (i == 0)
+        {
+            strJSON.append("\n");
+            strJSON.append(JSON_NAVIGATOR_NODES);
+            strJSON.append(JSON_NAVIGATOR_NODE_BEGIN);
+        }
+
+        StringBuffer strComponentTypeName(CBuildSetManager::getInstance()->getBuildSetComponentTypeName(i));
+        StringBuffer strComponentProcessName(CBuildSetManager::getInstance()->getBuildSetProcessName(i));
+
+        strJSON.append(JSON_NAVIGATOR_TEXT).append("\"").append(strComponentTypeName.str()).append("\",").append("\n");
+        strJSON.append(JSON_NAVIGATOR_KEY).append("\"#").append(CBuildSetManager::getInstance()->getBuildSetComponentFileName(i)).append("\"");
+
+        int nInstanceCount = CConfigSchemaHelper::getInstance()->getInstancesOfComponentType(strComponentTypeName.str());
+
+        if (CConfigSchemaHelper::getInstance()->getEnvFilePath() != NULL && strlen(CConfigSchemaHelper::getInstance()->getEnvFilePath()) > 0)
+        {
+            for (int ii = 0; ii < nInstanceCount; ii++)
+            {
+                if (ii == 0)
+                {
+                    strJSON.append(",\n");
+                    strJSON.append(JSON_NAVIGATOR_NODES);
+                    strJSON.append(JSON_NAVIGATOR_NODE_BEGIN);
+                }
+
+                strJSON.append(JSON_NAVIGATOR_TEXT).append("\"").append(CConfigSchemaHelper::getInstance()->getInstanceNameOfComponentType(strComponentProcessName.str(),ii)).append("\",").append("\n");
+                strJSON.append(JSON_NAVIGATOR_KEY).append("\"#").append(strComponentProcessName.str()).append("[").append(ii+1).append("]").append("\"\n");
+
+                if (ii+1 < nInstanceCount)
+                {
+                    strJSON.append("},\n{");
+                }
+                else
+                {
+                    strJSON.append("\n");
+                    strJSON.append(JSON_NAVIGATOR_NODE_END);
+                }
+            }
+            if (i+1 < nComponents)
+            {
+                strJSON.append("},\n{");
+            }
+            else
+            {
+                strJSON.append("\n");
+                strJSON.append(JSON_NAVIGATOR_NODE_END);
+            }
+        }
+        else if (i+1 < nComponents)
+        {
+            strJSON.append(",");
+        }
+        else
+        {
+            strJSON.append("\n");
+            strJSON.append(JSON_NAVIGATOR_NODE_END);
+        }
+    }
+    strJSON.append(JSON_NAVIGATOR_END);
+}

+ 77 - 0
configuration/configurator/JSONMarkUp.hpp

@@ -0,0 +1,77 @@
+#ifndef _JSONMARKUP_HPP_
+#define _JSONMARKUP_HPP_
+
+namespace CONFIGURATOR
+{
+
+/*static const char* JSON_BEGIN("\
+{\n\
+    \"data\": \n\
+    {\n\
+        \"PageTitle\": \"Configuration Manager\",\n\
+        \"APIVersion\": \"2.0\",\n\
+        \"toplevelcontainer\": \n\
+        [\n");
+
+static const char* JSON_END("\n\
+        ]\n\
+    }\n\
+}\n");*/
+
+static const char* JSON_BEGIN("\
+{\n\
+    \"content\": {\n\
+        \"innercontent\": [\n");
+
+static const char* JSON_END("\
+                       ]\n\
+    }\n\
+}\n");
+
+static const char* JSON_CONTENT_BEGIN(",\"content\" : {\n");
+
+static const char* JSON_CONTENT_END("}\n");
+
+static const char* JSON_LABEL("\"label\":");
+static const char* JSON_VALUES("\"values\":");
+static const char* JSON_VALUE("\"value\":");
+static const char* JSON_TYPE("\"type\":");
+static const char* JSON_TYPE_TAB("tab");
+static const char* JSON_TYPE_TABLE("table");
+static const char* JSON_TYPE_INPUT("input");
+static const char* JSON_TYPE_DROP_DOWN("dropdown");
+static const char* JSON_KEY("\"key\":");
+static const char* JSON_TOOLTIP("\"tooltip\": ");
+static const char* JSON_DEFAULT_VALUE("\"defaultValue\":");
+static const char* JSON_COLUMN_NAMES_VALUE("\"columnNames\":");
+static const char* JSON_INNER_CONTENT_BEGIN_1("\"innercontent\": [ \n");
+static const char* JSON_INNER_CONTENT_END("]");
+
+static const char* JSON_NAVIGATOR_BEGIN("[{\n");
+static const char* JSON_NAVIGATOR_END("}]\n");
+static const char* JSON_NAVIGATOR_NODE_BEGIN("[{\n");
+static const char* JSON_NAVIGATOR_NODE_END("}]\n");
+static const char* JSON_NAVIGATOR_TEXT("\"text\":");
+//static const char* JSON_NAVIGATOR_TYPE("\"type\":");
+static const char* JSON_NAVIGATOR_KEY("\"href\": ");
+//static const char* JSON_NAVIGATOR_KEY(JSON_DEFAULT_VALUE);
+static const char* JSON_NAVIGATOR_SELECTABLE("\"selectable\":");
+static const char* JSON_NAVIGATOR_NODES("\"nodes\":");
+
+
+#define CONTENT_INNER_CONTENT_BEGIN strJSON.append(JSON_CONTENT_BEGIN);offset += STANDARD_OFFSET_1;QuickOutPad(strJSON, offset);strJSON.append(JSON_INNER_CONTENT_BEGIN_1);
+#define INNER_CONTENT_END offset -= STANDARD_OFFSET_1;strJSON.append(JSON_INNER_CONTENT_END);
+#define CONTENT_CONTENT_END offset -= STANDARD_OFFSET_1;strJSON.append(JSON_CONTENT_END);
+
+class CJSONMarkUpHelper
+{
+
+public:
+    static void createUIContent(::StringBuffer &strJSON, unsigned int &offset, const char *pUIType, const char* pLabel, const char* pKey, const char *pToolTip = "", const char *pDefaultValue = "", const char* pValues = "", const char*  pValue = "");
+    //static void createUIContent(::StringBuffer &strJSON, unsigned int &offset, ::StringBuffer strUIType, ::StringBuffer strLabel, ::StringBuffer strKey, ::StringBuffer strToolTip = "", ::StringBuffer strDefaultValue = "", ::StringBuffer strValues = "", ::StringBuffer strValue = "");
+    static void getNavigatorJSON(::StringBuffer &strJSON);
+private:
+    static void markUpString(::StringBuffer &str);
+};
+}
+#endif // _JSONMARKUP_HPP_

+ 50 - 0
configuration/configurator/SchemaAll.hpp

@@ -0,0 +1,50 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaAnnotation.hpp"
+#include "SchemaAppInfo.hpp"
+#include "SchemaAttributes.hpp"
+#include "SchemaAttributeGroup.hpp"
+#include "SchemaChoice.hpp"
+#include "SchemaCommon.hpp"
+#include "SchemaComplexContent.hpp"
+#include "SchemaComplexType.hpp"
+#include "SchemaDocumentation.hpp"
+#include "SchemaElement.hpp"
+#include "SchemaExtension.hpp"
+#include "SchemaField.hpp"
+#include "SchemaFractionDigits.hpp"
+#include "SchemaInclude.hpp"
+#include "SchemaKey.hpp"
+#include "SchemaKeyRef.hpp"
+#include "SchemaLength.hpp"
+#include "SchemaMaxExclusive.hpp"
+#include "SchemaMinExclusive.hpp"
+#include "SchemaMaxInclusive.hpp"
+#include "SchemaMinInclusive.hpp"
+#include "SchemaMinLength.hpp"
+#include "SchemaMaxLength.hpp"
+#include "SchemaPattern.hpp"
+#include "SchemaRestriction.hpp"
+#include "SchemaSchema.hpp"
+#include "SchemaSelector.hpp"
+#include "SchemaSequence.hpp"
+#include "SchemaSimpleType.hpp"
+#include "SchemaTotalDigits.hpp"
+#include "SchemaUnique.hpp"
+#include "SchemaWhiteSpace.hpp"
+#include "SchemaSimpleContent.hpp"

+ 86 - 0
configuration/configurator/SchemaAnnotation.cpp

@@ -0,0 +1,86 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include <cassert>
+#include "XMLTags.h"
+#include "jptree.hpp"
+
+#include "SchemaAnnotation.hpp"
+#include "SchemaDocumentation.hpp"
+#include "SchemaAppInfo.hpp"
+
+using namespace CONFIGURATOR;
+
+#define StringBuffer ::StringBuffer
+#define IPropertyTree ::IPropertyTree
+
+CAnnotation* CAnnotation::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+
+    if (pSchemaRoot == NULL)
+        return NULL;
+
+    StringBuffer strXPathExt(xpath);
+
+    strXPathExt.append("/").append(XSD_TAG_DOCUMENTATION);
+    CDocumentation *pDocumentation = CDocumentation::load(NULL, pSchemaRoot, strXPathExt.str());
+
+    strXPathExt.clear().append(xpath).append("/").append(XSD_TAG_APP_INFO);
+    CAppInfo *pAnnInfo = CAppInfo::load(NULL, pSchemaRoot, strXPathExt.str());
+
+    CAnnotation *pAnnotation = new CAnnotation(pParentNode, pDocumentation, pAnnInfo);
+    pAnnotation->setXSDXPath(xpath);
+
+    SETPARENTNODE(pDocumentation, pAnnotation);
+    SETPARENTNODE(pAnnInfo, pAnnotation);
+
+    return pAnnotation;
+}
+
+void CAnnotation::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+    QuickOutHeader(cout, XSD_ANNOTATION_STR, offset);
+
+    QUICK_OUT(cout, XSDXPath, offset);
+
+    if (m_pAppInfo != NULL)
+        m_pAppInfo->dump(cout, offset);
+
+    if (m_pDocumentation != NULL)
+        m_pDocumentation->dump(cout, offset);
+
+    QuickOutFooter(cout, XSD_ANNOTATION_STR, offset);
+}
+
+void CAnnotation::getDocumentation(StringBuffer &strDoc) const
+{
+    if (m_pAppInfo != NULL)
+        m_pAppInfo->getDocumentation(strDoc);
+    if (m_pDocumentation != NULL)
+        m_pDocumentation->getDocumentation(strDoc);
+}
+
+void CAnnotation::loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+{
+    if (m_pAppInfo != NULL)
+        m_pAppInfo->loadXMLFromEnvXml(pEnvTree);
+
+    if (m_pDocumentation != NULL)
+        m_pDocumentation->loadXMLFromEnvXml(pEnvTree);
+}

+ 69 - 0
configuration/configurator/SchemaAnnotation.hpp

@@ -0,0 +1,69 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_ANNOTATION_HPP_
+#define _SCHEMA_ANNOTATION_HPP_
+
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CDocumentation;
+class CAppInfo;
+
+class CAnnotation : public CXSDNode
+{
+public:
+
+    virtual ~CAnnotation()
+    {
+    }
+
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+
+    const CDocumentation* getDocumentation() const
+    {
+        return m_pDocumentation;
+    }
+
+    virtual void getDocumentation(StringBuffer &strDoc) const;
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+
+    const CAppInfo* getAppInfo() const
+    {
+        return m_pAppInfo;
+    }
+    static CAnnotation* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath = NULL);
+
+protected:
+
+    CAnnotation(CXSDNodeBase* pParentNode, CDocumentation *pDocumenation = NULL, CAppInfo *pAppInfp = NULL) : CXSDNode::CXSDNode(pParentNode, XSD_ANNOTATION), m_pDocumentation(pDocumenation), m_pAppInfo(pAppInfp)
+    {
+    }
+
+    CDocumentation* m_pDocumentation;
+    CAppInfo* m_pAppInfo;
+
+private:
+
+    CAnnotation() : CXSDNode::CXSDNode(NULL, XSD_ANNOTATION)
+    {
+    }
+};
+}
+#endif // _SCHEMA_ANNOTATION_HPP_

+ 131 - 0
configuration/configurator/SchemaAppInfo.cpp

@@ -0,0 +1,131 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jptree.hpp"
+#include "XMLTags.h"
+#include "SchemaAppInfo.hpp"
+#include "DocumentationMarkup.hpp"
+
+using namespace CONFIGURATOR;
+
+#define IPropertyTree ::IPropertyTree
+
+CAppInfo* CAppInfo::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    if (pSchemaRoot == NULL)
+        return NULL;
+
+    if (pSchemaRoot->queryPropTree(xpath) == NULL)
+        return NULL;   // No AppInfo node
+
+    StringBuffer strXPathViewType(xpath);
+    strXPathViewType.append("/").append(TAG_VIEWTYPE);
+    StringBuffer strXPathColIndex(xpath);
+    strXPathColIndex.append("/").append(TAG_COLINDEX);
+    StringBuffer strXPathToolTip(xpath);
+    strXPathToolTip.append("/").append(TAG_TOOLTIP);
+    StringBuffer strXPathTitle(xpath);
+    strXPathTitle.append("/").append(TAG_TITLE);
+    StringBuffer strXPathWidth(xpath);
+    strXPathWidth.append("/").append(TAG_WIDTH);
+    StringBuffer strXPathAutoGenDefaultValue(xpath);
+    strXPathAutoGenDefaultValue.append("/").append(TAG_AUTOGENWIZARD);
+    StringBuffer strXPathAutoGenForWizard(xpath);
+    strXPathAutoGenForWizard.append("/").append(TAG_AUTOGENDEFAULTVALUE);
+    StringBuffer strXPathAutoGenDefaultForMultiNode(xpath);
+    strXPathAutoGenDefaultForMultiNode.append("/").append(TAG_AUTOGENDEFAULTVALUEFORMULTINODE);
+    StringBuffer strXPathViewChildNodes(xpath);
+    strXPathViewChildNodes.append("/").append(TAG_VIEWCHILDNODES);
+    StringBuffer strXPathXPath(xpath);
+    strXPathXPath.append("/").append(TAG_XPATH);
+    StringBuffer strXPathDocID(xpath);
+    strXPathDocID.append("/").append(TAG_DOC_ID);
+    StringBuffer strXPathDocLineBreak(xpath);
+    strXPathDocLineBreak.append("/").append(TAG_DOC_USE_LINE_BREAK);
+
+    StringBuffer strViewType;
+    StringBuffer strColIndex;
+    StringBuffer strToolTip;
+    StringBuffer strTitle;
+    StringBuffer strWidth;
+    StringBuffer strAutoGenForWizard;
+    StringBuffer strAutoGenDefaultValue;
+    StringBuffer strAutoGenDefaultForMultiNode;
+    StringBuffer strViewChildNodes;
+    StringBuffer strXPath;
+    StringBuffer strDocTableID;
+    bool bDocLineBreak = false;
+
+    if (pSchemaRoot->queryPropTree(strXPathViewType.str()) != NULL)
+        strViewType.append(pSchemaRoot->queryPropTree(strXPathViewType.str())->queryProp(""));
+    if (pSchemaRoot->queryPropTree(strXPathColIndex.str()) != NULL)
+        strColIndex.append(pSchemaRoot->queryPropTree(strXPathColIndex.str())->queryProp(""));
+    if (pSchemaRoot->queryPropTree(strXPathToolTip.str()) != NULL)
+        strToolTip.append(pSchemaRoot->queryPropTree(strXPathToolTip.str())->queryProp(""));
+    if (pSchemaRoot->queryPropTree(strXPathTitle.str()) != NULL)
+        strTitle.append(pSchemaRoot->queryPropTree(strXPathTitle.str())->queryProp(""));
+    if (pSchemaRoot->queryPropTree(strXPathWidth.str()) != NULL)
+        strWidth.append(pSchemaRoot->queryPropTree(strXPathWidth.str())->queryProp(""));
+    if (pSchemaRoot->queryPropTree(strXPathAutoGenForWizard.str()) != NULL)
+        strAutoGenForWizard.append(pSchemaRoot->queryPropTree(strXPathAutoGenForWizard.str())->queryProp(""));
+    if (pSchemaRoot->queryPropTree(strXPathAutoGenDefaultValue.str()) != NULL)
+        strAutoGenDefaultValue.append(pSchemaRoot->queryPropTree(strXPathAutoGenDefaultValue.str())->queryProp(""));
+    if (pSchemaRoot->queryPropTree(strXPathAutoGenDefaultForMultiNode.str()) != NULL)
+        strAutoGenDefaultForMultiNode.append(pSchemaRoot->queryPropTree(strXPathAutoGenDefaultForMultiNode.str())->queryProp(""));
+    if (pSchemaRoot->queryPropTree(strXPathViewChildNodes.str()) != NULL)
+        strViewChildNodes.append(pSchemaRoot->queryPropTree(strXPathViewChildNodes.str())->queryProp(""));
+    if (pSchemaRoot->queryPropTree(strXPathXPath.str()) != NULL)
+        strXPath.append(pSchemaRoot->queryPropTree(strXPathXPath.str())->queryProp(""));
+    if (pSchemaRoot->queryPropTree(strXPathDocID.str()) != NULL)
+        strDocTableID.append(pSchemaRoot->queryPropTree(strXPathDocID.str())->queryProp(""));
+    if (pSchemaRoot->queryPropTree(strXPathDocLineBreak.str()) != NULL)
+        bDocLineBreak = true;
+
+    CAppInfo *pAppInfo = new CAppInfo(pParentNode, strViewType.str(),  strColIndex.str(), strToolTip.str(), strTitle.str(), strWidth.str(), strAutoGenForWizard.str(), strAutoGenDefaultValue.str(), NULL, strViewChildNodes.str(), strXPath.str(), strDocTableID.str(), bDocLineBreak);
+    pAppInfo->setXSDXPath(xpath);
+
+    return pAppInfo;
+}
+
+void CAppInfo::dump(::std::ostream &cout, unsigned int offset) const
+{
+    offset += STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_APP_INFO_STR, offset);
+
+    QUICK_OUT(cout, Title, offset);
+    QUICK_OUT(cout, ViewType, offset);
+    QUICK_OUT(cout, ToolTip, offset);
+    QUICK_OUT(cout, ColIndex, offset);
+    QUICK_OUT(cout, Width, offset);
+    QUICK_OUT(cout, AutoGenForWizard, offset);
+    QUICK_OUT(cout, AutoGenDefaultValue, offset);
+    QUICK_OUT(cout, AutoGenDefaultValueForMultiNode, offset);
+    QUICK_OUT(cout, ViewChildNodes, offset);
+    QUICK_OUT(cout, XPath, offset);
+    QUICK_OUT(cout, XSDXPath, offset);
+
+    QuickOutFooter(cout, XSD_APP_INFO_STR, offset);
+}
+
+void CAppInfo::getDocumentation(StringBuffer &strDoc) const
+{
+}
+
+void CAppInfo::loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+{
+}

+ 77 - 0
configuration/configurator/SchemaAppInfo.hpp

@@ -0,0 +1,77 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_APP_INFO_HPP_
+#define _SCHEMA_APP_INFO_HPP_
+
+#include "SchemaCommon.hpp"
+#include "jstring.hpp"
+
+namespace CONFIGURATOR
+{
+class IPropertyTree;
+
+class CAppInfo : public CXSDNodeBase
+{
+public:
+
+    virtual ~CAppInfo()
+    {
+    }
+
+    GETTERSETTER(ViewType)
+    GETTERSETTER(ColIndex)
+    GETTERSETTER(ToolTip)
+    GETTERSETTER(Title)
+    GETTERSETTER(AutoGenForWizard)
+    GETTERSETTER(AutoGenDefaultValue)
+    GETTERSETTER(Width)
+    GETTERSETTER(AutoGenDefaultValueForMultiNode)
+    GETTERSETTER(ViewChildNodes)
+    GETTERSETTER(XPath)
+    GETTERSETTER(DocTableID)
+
+    virtual void dump(::std::ostream &cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(StringBuffer &strDoc) const;
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+
+    bool getDocLineBreak() const
+    {
+        return m_bDocLineBreak;
+    }
+    static CAppInfo* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+protected:
+
+    CAppInfo(CXSDNodeBase* pParentNode, const char *pViewType = NULL, const char *pColIndex = NULL, const char* pToolTip = NULL, const char* pTitle = NULL, const char* pWidth = NULL, const char* pAutoGenForWizard = NULL,\
+             const char* pAutoGenDefaultValue = NULL, const char* pAutoGenDefaultForMultiNode = NULL, const char* pViewChildNodes = NULL, const char* pXPath = NULL, const char* pDocTableID = NULL, bool bDocLineBreak = false)\
+        : CXSDNodeBase::CXSDNodeBase(pParentNode, XSD_APP_INFO), m_strViewType(pViewType), m_strColIndex(pColIndex), m_strToolTip(pToolTip), m_strTitle(pTitle), m_strWidth(pWidth), m_strAutoGenForWizard(pAutoGenForWizard),\
+          m_strAutoGenDefaultValue(pAutoGenDefaultValue), m_strAutoGenDefaultValueForMultiNode(pAutoGenDefaultForMultiNode), m_strViewChildNodes(pViewChildNodes), m_strXPath(pXPath), m_strDocTableID(pDocTableID),\
+          m_bDocLineBreak(bDocLineBreak)
+    {
+    }
+
+    bool m_bDocLineBreak;
+
+private:
+
+    CAppInfo(CXSDNodeBase* pParentNode = NULL) : CXSDNodeBase::CXSDNodeBase(pParentNode, XSD_APP_INFO)
+    {
+    }
+};
+}
+#endif // _SCHEMA_APP_INFO_HPP_

+ 357 - 0
configuration/configurator/SchemaAttributeGroup.cpp

@@ -0,0 +1,357 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaAttributeGroup.hpp"
+#include "DocumentationMarkup.hpp"
+#include "ConfigSchemaHelper.hpp"
+#include "jptree.hpp"
+#include "SchemaMapManager.hpp"
+#include"JSONMarkUp.hpp"
+
+using namespace CONFIGURATOR;
+
+#define StringBuffer ::StringBuffer
+#define IPropertyTree ::IPropertyTree
+
+const CXSDNodeBase* CAttributeGroup::getNodeByTypeAndNameAscending(NODE_TYPES eNodeType, const char *pName) const
+{
+    const CXSDNodeBase* pMatchingNode = NULL;
+
+    if (eNodeType == this->getNodeType() && (pName != NULL ? !strcmp(pName, this->getNodeTypeStr()) : true))
+    {
+        assert(pName != NULL); // for now pName should always be populated
+        return this;
+    }
+
+    if (m_pAttributeArray != NULL)
+        pMatchingNode =  m_pAttributeArray->getNodeByTypeAndNameAscending(eNodeType, pName);
+    if (pMatchingNode == NULL && m_pAttributeArray != NULL)
+         pMatchingNode =  m_pAttributeArray->getNodeByTypeAndNameDescending(eNodeType, pName);
+    return pMatchingNode;
+}
+
+CAttributeGroup::~CAttributeGroup()
+{
+}
+
+const CXSDNodeBase* CAttributeGroup::getNodeByTypeAndNameDescending(NODE_TYPES eNodeType, const char *pName) const
+{
+    const CXSDNodeBase* pMatchingNode = NULL;
+
+    if (eNodeType == this->getNodeType() && (pName != NULL ? !strcmp(pName, this->getNodeTypeStr()) : true))
+    {
+        assert(pName != NULL); // for now pName should always be populated
+        return this;
+    }
+
+    if (m_pAttributeArray != NULL)
+        pMatchingNode =  m_pAttributeArray->getNodeByTypeAndNameDescending(eNodeType, pName);
+    return pMatchingNode;
+}
+
+void CAttributeGroup::dump(::std::ostream &cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_ATTRIBUTE_GROUP_STR, offset);
+
+    QUICK_OUT(cout, Name,       offset);
+    QUICK_OUT(cout, Ref,        offset);
+    QUICK_OUT(cout, ID,         offset);
+    QUICK_OUT(cout, XSDXPath,   offset);
+    QUICK_OUT(cout, EnvXPath,   offset);
+
+    if (m_pAttributeArray != NULL)
+        m_pAttributeArray->dump(cout, offset);
+
+    QuickOutFooter(cout, XSD_ATTRIBUTE_GROUP_STR, offset);
+}
+
+void CAttributeGroup::getDocumentation(StringBuffer &strDoc) const
+{
+    if (this->getRef() != NULL && this->getRef()[0] != 0 && m_pRefAttributeGroup != NULL)
+    {
+        strDoc.appendf("%s%s%s", DM_TITLE_BEGIN, m_pRefAttributeGroup->getName(), DM_TITLE_END);
+        DEBUG_MARK_STRDOC;
+
+        if (m_pRefAttributeGroup->getConstAttributeArray() != NULL)
+            m_pRefAttributeGroup->getConstAttributeArray()->getDocumentation(strDoc);
+    }
+}
+
+void CAttributeGroup::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    if (this->getRef() != NULL && this->getRef()[0] != 0 && m_pRefAttributeGroup != NULL)
+    {
+        if (m_pRefAttributeGroup->getConstAttributeArray() != NULL)
+            m_pRefAttributeGroup->getAttributeArray()->populateEnvXPath(strXPath);
+    }
+    this->setEnvXPath(strXPath);
+}
+
+void CAttributeGroup::loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+{
+    assert(pEnvTree != NULL);
+
+    if (m_pAttributeArray != NULL)
+    {
+        try
+        {
+            m_pAttributeArray->loadXMLFromEnvXml(pEnvTree);
+        }
+        catch (...)
+        {
+            // validation check needed here
+        }
+    }
+    if (m_pAnnotation != NULL)
+    {
+        try
+        {
+            m_pAnnotation->loadXMLFromEnvXml(pEnvTree);
+        }
+        catch (...)
+        {
+            // validation check needed here
+        }
+    }
+    if (m_pRefAttributeGroup != NULL)
+    {
+        try
+        {
+            m_pRefAttributeGroup->loadXMLFromEnvXml(pEnvTree);
+        }
+        catch (...)
+        {
+            // validation check needed here
+        }
+    }
+}
+
+const char* CAttributeGroup::getXML(const char* /*pComponent*/)
+{
+    if (m_strXML.length() == 0 && m_pAttributeArray != NULL)
+    {
+        for (int idx = 0; idx < m_pAttributeArray->length(); idx++)
+        {
+            m_strXML.append("\n").append(m_pAttributeArray->item(idx).getXML(NULL));
+        }
+    }
+    return m_strXML.str();
+}
+
+CAttributeGroup* CAttributeGroup::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    if (pSchemaRoot == NULL || xpath == NULL)
+        return NULL;
+
+    assert(pParentNode->getNodeType() != XSD_ATTRIBUTE_GROUP);
+    CAttributeGroup *pAttributeGroup = new CAttributeGroup(pParentNode);
+
+    pAttributeGroup->setXSDXPath(xpath);
+    assert(pAttributeGroup);
+
+    if (pAttributeGroup == NULL)
+        return NULL;
+
+    IPropertyTree *pTree = pSchemaRoot->queryPropTree(xpath);
+    if (pTree == NULL)
+        return NULL;
+
+    pAttributeGroup->setName(pTree->queryProp(XML_ATTR_NAME));
+    pAttributeGroup->setID(pTree->queryProp(XML_ATTR_ID));
+    pAttributeGroup->setRef(pTree->queryProp(XML_ATTR_REF));
+
+    if (pAttributeGroup->getRef() != NULL && pAttributeGroup->getRef()[0] != 0)
+    {
+        if (pAttributeGroup->getName() != NULL && pAttributeGroup->getName()[0] != 0)
+        {
+            assert(false); //can't have both nameand ref set
+            return NULL;
+        }
+        else
+            CConfigSchemaHelper::getInstance()->addAttributeGroupToBeProcessed(pAttributeGroup);
+    }
+    else if (pAttributeGroup->getName() != NULL && pAttributeGroup->getName()[0] != 0)
+        CConfigSchemaHelper::getInstance()->getSchemaMapManager()->setAttributeGroupTypeWithName(pAttributeGroup->getName(), pAttributeGroup);
+
+    StringBuffer strXPath(xpath);
+    strXPath.append("/").append(XSD_TAG_ATTRIBUTE);
+
+    CAttributeArray *pAttribArray = CAttributeArray::load(pAttributeGroup, pSchemaRoot, strXPath.str());
+    if (pAttribArray != NULL)
+        pAttributeGroup->setAttributeArray(pAttribArray);
+
+    strXPath.setf("%s/%s",xpath, XSD_TAG_ANNOTATION);
+    pAttributeGroup->setAnnotation(CAnnotation::load(pAttributeGroup, pSchemaRoot, strXPath.str()));
+
+    return pAttributeGroup;
+}
+
+void CAttributeGroup::getJSON(StringBuffer &strJSON, unsigned int offset, int idx) const
+{
+    assert(this->getRef() != NULL);
+
+    if (this->getRef() != NULL && this->getRef()[0] != 0 && m_pRefAttributeGroup != NULL)
+    {
+        if (m_pRefAttributeGroup->getConstAttributeArray() != NULL && m_pRefAttributeGroup->getConstAttributeArray()->length() > 0)
+        {
+            QuickOutPad(strJSON, offset);
+            CONTENT_INNER_CONTENT_BEGIN
+            m_pRefAttributeGroup->getConstAttributeArray()->getJSON(strJSON, offset);
+        }
+    }
+}
+
+CAttributeGroupArray::~CAttributeGroupArray()
+{
+}
+
+CAttributeGroupArray* CAttributeGroupArray::load(const char* pSchemaFile)
+{
+    assert(false);  // Should never call this?
+
+    if (pSchemaFile == NULL)
+        return NULL;
+
+    Linked<IPropertyTree> pSchemaRoot;
+    StringBuffer schemaPath;
+
+    schemaPath.appendf("%s%s", DEFAULT_SCHEMA_DIRECTORY, pSchemaFile);
+    pSchemaRoot.setown(createPTreeFromXMLFile(schemaPath.str()));
+
+    return CAttributeGroupArray::load(NULL, pSchemaRoot, XSD_TAG_ATTRIBUTE_GROUP);
+}
+
+CAttributeGroupArray* CAttributeGroupArray::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+
+    if (pSchemaRoot == NULL || xpath == NULL)
+        return NULL;
+
+    CAttributeGroupArray *pAttribGroupArray = new CAttributeGroupArray(pParentNode);
+    pAttribGroupArray->setXSDXPath(xpath);
+
+    StringBuffer strXPathExt(xpath);
+
+    // to iterate over xs:attributeGroup nodes at same level in tree
+    Owned<IPropertyTreeIterator> attribGroupsIter = pSchemaRoot->getElements(strXPathExt.str());
+
+    int count = 1;
+    ForEach(*attribGroupsIter)
+    {
+        strXPathExt.clear().appendf("%s[%d]", xpath, count);
+
+        CAttributeGroup *pAttribGroup = CAttributeGroup::load(pAttribGroupArray, pSchemaRoot, strXPathExt.str());
+
+        if (pAttribGroup != NULL)
+            pAttribGroupArray->append(*pAttribGroup);
+
+        count++;
+    }
+
+    if (pAttribGroupArray->length() == 0)
+    {
+        delete pAttribGroupArray;
+        return NULL;
+    }
+    return pAttribGroupArray;
+}
+
+void CAttributeGroupArray::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout,XSD_ATTRIBUTE_GROUP_ARRAY_STR, offset);
+
+    QUICK_OUT(cout, XSDXPath, offset);
+    QUICK_OUT(cout, EnvXPath,  offset);
+    QUICK_OUT_ARRAY(cout, offset);
+
+    QuickOutFooter(cout,XSD_ATTRIBUTE_GROUP_ARRAY_STR, offset);
+}
+
+void CAttributeGroupArray::getDocumentation(StringBuffer &strDoc) const
+{
+    StringBuffer strDocDupe1(strDoc);
+
+    QUICK_DOC_ARRAY(strDocDupe1);
+
+    if (strDocDupe1.length() == strDoc.length())  // hack
+       return;
+
+    for (int idx=0; idx < this->length(); idx++)
+    {
+        strDoc.append(DM_SECT3_BEGIN);
+        (this->item(idx)).getDocumentation(strDoc);
+        strDoc.append(DM_SECT3_END);
+    }
+}
+
+void CAttributeGroupArray::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    assert(index == 1);  // Only 1 array of elements per node
+
+    for (int idx=0; idx < this->length(); idx++)
+    {
+        (this->item(idx)).populateEnvXPath(strXPath, 1);
+    }
+    this->setEnvXPath(strXPath);
+}
+
+void CAttributeGroupArray::loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+{
+    QUICK_LOAD_ENV_XML(pEnvTree)
+}
+
+void CAttributeGroupArray::getJSON(StringBuffer &strJSON, unsigned int offset, int idx) const
+{
+    int nLength = this->length();
+
+    offset += STANDARD_OFFSET_1;
+    QuickOutPad(strJSON, offset);
+
+    for (int lidx = 0; lidx < nLength; lidx++)
+    {
+        if (lidx != 0)
+        {
+            if (lidx != 0)
+            {
+                QuickOutPad(strJSON, offset);
+                strJSON.append(",");
+            }
+        }
+
+        strJSON.append("{");
+        CJSONMarkUpHelper::createUIContent(strJSON, offset, JSON_TYPE_TAB, this->item(lidx).getRef(), this->getEnvXPath());
+
+        if (lidx != 0)
+        {
+            strJSON.append("\n");
+        }
+
+        this->item(lidx).getJSON(strJSON, offset, lidx);
+        strJSON.append("]}}\n");
+
+        if (lidx+1 < nLength)
+        {
+            QuickOutPad(strJSON, offset);
+        }
+    }
+}

+ 119 - 0
configuration/configurator/SchemaAttributeGroup.hpp

@@ -0,0 +1,119 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_ATTRIBUTE_GROUP_HPP_
+#define _SCHEMA_ATTRIBUTE_GROUP_HPP_
+
+#include "SchemaCommon.hpp"
+#include "SchemaAttributes.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CAttributeGroup : public CXSDNode
+{
+public:
+
+    virtual ~CAttributeGroup();
+
+    GETTERSETTER(Name)
+    GETTERSETTER(Ref)
+    GETTERSETTER(ID)
+
+    virtual const CXSDNodeBase* getNodeByTypeAndNameAscending(NODE_TYPES eNodeType, const char *pName) const;
+    virtual const CXSDNodeBase* getNodeByTypeAndNameDescending(NODE_TYPES eNodeType, const char *pName) const;
+
+    const CAttributeArray* getConstAttributeArray() const
+    {
+        return m_pAttributeArray;
+    }
+
+    void setAttributeArray(CAttributeArray *pAttribArray)
+    {
+        if (m_pAttributeArray != NULL)
+            m_pAttributeArray->Release();
+
+        m_pAttributeArray = pAttribArray;
+    }
+
+    void setRefNode(CAttributeGroup* pAttributeGroup)
+    {
+        assert(pAttributeGroup != NULL);
+        m_pRefAttributeGroup = pAttributeGroup;
+    }
+
+    virtual const char* getXML(const char* /*pComponent*/);
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const;
+    virtual void getJSON(::StringBuffer &strJSON, unsigned int offset = 0, int idx = -1) const;
+
+    virtual CAnnotation* getAnnotation() const
+    {
+        return m_pAnnotation;
+    }
+
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+
+    static CAttributeGroup* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+protected:
+
+   CAttributeGroup(CXSDNodeBase* pParentNode = NULL, CAttributeArray *pAttribArray = NULL, CAnnotation *pAnnotation = NULL) : CXSDNode::CXSDNode(pParentNode, XSD_ATTRIBUTE_GROUP), m_pAttributeArray(pAttribArray), m_pRefAttributeGroup(NULL), m_pAnnotation(pAnnotation)
+    {
+    }
+
+    virtual void setAnnotation(CAnnotation *pAnnotation)
+    {
+        m_pAnnotation = pAnnotation;
+    }
+
+    CAttributeArray* getAttributeArray() const
+    {
+        return m_pAttributeArray;
+    }
+
+    CAttributeGroup *m_pRefAttributeGroup;
+    CAttributeArray *m_pAttributeArray;
+    CAnnotation     *m_pAnnotation;
+
+private:
+};
+
+class CAttributeGroupArray : public ::CIArrayOf<CAttributeGroup>, public InterfaceImpl, public CXSDNodeBase
+{
+public:
+
+    CAttributeGroupArray(CXSDNodeBase* pParentNode = NULL) : CXSDNodeBase::CXSDNodeBase(pParentNode, XSD_ATTRIBUTE_GROUP_ARRAY)
+    {
+    }
+
+    virtual ~CAttributeGroupArray();
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const;
+    virtual void getJSON(::StringBuffer &strJSON, unsigned int offset = 0, int idx = -1) const;
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+    static CAttributeGroupArray* load(const char* pSchemaFile);
+    static CAttributeGroupArray* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+protected:
+private:
+};
+
+}
+#endif // _SCHEMA_ATTRIBUTE_GROUP_HPP_

+ 594 - 0
configuration/configurator/SchemaAttributes.cpp

@@ -0,0 +1,594 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jptree.hpp"
+#include "jarray.hpp"
+#include "jlog.hpp"
+#include "SchemaAttributes.hpp"
+#include "SchemaCommon.hpp"
+#include "SchemaAppInfo.hpp"
+#include "SchemaSimpleType.hpp"
+#include "DocumentationMarkup.hpp"
+#include "ConfigSchemaHelper.hpp"
+#include "ExceptionStrings.hpp"
+#include "SchemaMapManager.hpp"
+#include "ConfiguratorMain.hpp"
+#include "SchemaKey.hpp"
+#include "SchemaKeyRef.hpp"
+#include "SchemaSimpleType.hpp"
+#include "SchemaAppInfo.hpp"
+#include "JSONMarkUp.hpp"
+#include "SchemaEnumeration.hpp"
+#include "SchemaElement.hpp"
+
+using namespace CONFIGURATOR;
+
+#define StringBuffer ::StringBuffer
+#define IPropertyTree ::IPropertyTree
+
+CAttribute::~CAttribute()
+{
+}
+
+bool CAttribute::isHidden()
+{
+    if(this->getAnnotation()->getAppInfo() != NULL && !stricmp(this->getAnnotation()->getAppInfo()->getViewType(),"hidden"))
+        return true;
+
+    return false;
+}
+
+const char* CAttribute::getTitle() const
+{
+    if (this->m_pAnnotation != NULL && this->m_pAnnotation->getAppInfo() != NULL && this->m_pAnnotation->getAppInfo()->getTitle() != NULL && this->m_pAnnotation->getAppInfo()->getTitle()[0] != 0)
+        return this->m_pAnnotation->getAppInfo()->getTitle();
+    else
+        return this->getName();
+}
+
+const char* CAttribute::getXML(const char* pComponent)
+{
+    if (m_strXML.length() == 0)
+        m_strXML.append(getName()).append("=\"").append(getDefault()).append("\"");
+    return m_strXML.str();
+}
+
+void CAttribute::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout,XSD_ATTRIBUTE_STR, offset);
+
+    QUICK_OUT(cout, Name,   offset);
+    QUICK_OUT(cout, Type,   offset);
+    QUICK_OUT(cout, Default,offset);
+    QUICK_OUT(cout, Use,    offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QUICK_OUT(cout, EnvXPath,  offset);
+    QUICK_OUT(cout, EnvValueFromXML,  offset);
+
+    if (m_pAnnotation != NULL)
+        m_pAnnotation->dump(cout, offset);
+    if (m_pSimpleTypeArray != NULL)
+        m_pSimpleTypeArray->dump(cout, offset);
+
+    QuickOutFooter(cout,XSD_ATTRIBUTE_STR, offset);
+}
+
+void CAttribute::getDocumentation(StringBuffer &strDoc) const
+{
+    const char *pName = this->getTitle();
+    const char *pToolTip = NULL;
+    const char *pDefaultValue = this->getDefault();
+    const char *pRequired = this->getUse();
+
+    if (m_pAnnotation != NULL && m_pAnnotation->getAppInfo() != NULL)
+    {
+        const CAppInfo *pAppInfo = m_pAnnotation->getAppInfo();
+        const char* pViewType = pAppInfo->getViewType();
+
+        if (pViewType != NULL && stricmp("hidden", pViewType) == 0)
+            return; // HIDDEN
+        else
+            pToolTip = pAppInfo->getToolTip();
+    }
+
+    strDoc.appendf("<%s>\n", DM_TABLE_ROW);
+    strDoc.appendf("<%s>%s</%s>\n", DM_TABLE_ENTRY, pName, DM_TABLE_ENTRY);
+    strDoc.appendf("<%s>%s</%s>\n", DM_TABLE_ENTRY, pToolTip, DM_TABLE_ENTRY);
+
+    if (m_pSimpleTypeArray == NULL)
+        strDoc.appendf("<%s>%s</%s>\n", DM_TABLE_ENTRY, pDefaultValue, DM_TABLE_ENTRY);
+    else
+    {
+        StringBuffer strDocTemp(pDefaultValue);
+        m_pSimpleTypeArray->getDocumentation(strDocTemp);
+
+        strDoc.appendf("<%s>%s</%s>\n", DM_TABLE_ENTRY, strDocTemp.str(), DM_TABLE_ENTRY);
+    }
+
+    if (m_pAnnotation != NULL && m_pAnnotation->getAppInfo() != NULL && m_pAnnotation->getAppInfo()->getDocLineBreak() == true)
+        strDoc.appendf("<%s>%s%s</%s>\n", DM_TABLE_ENTRY, DM_LINE_BREAK2, pRequired, DM_TABLE_ENTRY);
+    else
+        strDoc.appendf("<%s>%s</%s>\n", DM_TABLE_ENTRY, pRequired, DM_TABLE_ENTRY);
+    strDoc.appendf("</%s>\n", DM_TABLE_ROW);
+}
+
+void CAttribute::getJSON(StringBuffer &strJSON, unsigned int offset, int idx) const
+{
+    StringBuffer strToolTip;
+    StringBuffer strValues;
+
+    if (this->getAnnotation() && this->getAnnotation()->getAppInfo() && this->getAnnotation()->getAppInfo()->getToolTip())
+    {
+        strToolTip.set(this->getAnnotation()->getAppInfo()->getToolTip());
+    }
+    if (this->getSimpleTypeArray() &&  this->getSimpleTypeArray()->length() > 0 &&
+            this->getSimpleTypeArray()->item(0).getRestriction() && this->getSimpleTypeArray()->item(0).getRestriction()->getEnumerationArray() &&
+            this->getSimpleTypeArray()->item(0).getRestriction()->getEnumerationArray()->length() > 0)  // why would I have more than 1 simpletype here for a dropdown?
+    {
+        int nLength = this->getSimpleTypeArray()->item(0).getRestriction()->getEnumerationArray()->length();
+
+        for (int lidx = 0; lidx < nLength; lidx++)
+        {
+            if (lidx > 0)
+            {
+                strValues.append("\" , \"");
+            }
+            strValues.append(this->getSimpleTypeArray()->item(0).getRestriction()->getEnumerationArray()->item(lidx).getValue());
+        }
+    }
+
+    StringBuffer strInstanceValues;
+    StringBuffer strKeys;
+    const CElementArray *pElementArray = dynamic_cast<const CElementArray*>(this->getParentNodeByType(XSD_ELEMENT_ARRAY));
+
+    if (pElementArray != NULL && pElementArray->getParentNodeByType(XSD_ELEMENT_ARRAY) != NULL &&  pElementArray->getParentNodeByType(XSD_ELEMENT_ARRAY)->getNodeType() != XSD_SCHEMA)
+    {
+        for (int i = 0; i < pElementArray->ordinality(); i++)
+        {
+            if (i != 0)
+            {
+                strInstanceValues.append(", ");
+                strKeys.append(",");
+            }
+            else
+            {
+                strInstanceValues.append("[");
+                strKeys.append("[");
+            }
+
+            const CAttribute *pAttribute = const_cast<const CAttribute*>(&(pElementArray->item(i).getComplexTypeArray()->item(0).getAttributeArray()->item(idx)));
+            assert(pAttribute != NULL);
+
+            strInstanceValues.appendf("\"%s\"",pAttribute->getInstanceValue());
+            strKeys.appendf("\"%s\"",pAttribute->getEnvXPath());
+        }
+
+        strInstanceValues.append("]");
+        strKeys.append("]");
+    }
+    else
+    {
+        strInstanceValues.appendf("\"%s\"",this->getInstanceValue());
+    }
+
+    CJSONMarkUpHelper::createUIContent(strJSON, offset, strValues.length() > 0 ? JSON_TYPE_DROP_DOWN : JSON_TYPE_INPUT, this->getTitle(),\
+                                       strKeys.length() > 0 ? strKeys.str() : this->getEnvXPath(), strToolTip.str(), this->getDefault(), strValues.str(), strInstanceValues.str());
+}
+
+void CAttribute::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    assert(this->getName() != NULL);
+
+    const char *pChar = strrchr(strXPath.str(),'[');
+    assert(pChar != NULL && strlen(pChar) >= 3);
+
+    /*strXPath.setLength(strXPath.length()-strlen(pChar));  // remove [N] from XPath;
+    strXPath.appendf("[%d]", index);*/
+    strXPath.append("/").append("[@").append(this->getName()).append("]");
+    this->setEnvXPath(strXPath.str());
+
+    //PROGLOG("Mapping attribute with XPATH of %s to %p", this->getEnvXPath(), this);
+
+    CConfigSchemaHelper::getInstance()->getSchemaMapManager()->addMapOfXPathToAttribute(this->getEnvXPath(), this);
+    CConfigSchemaHelper::getInstance()->appendAttributeXPath(this->getEnvXPath());
+
+    if (this->m_pSimpleTypeArray != NULL)
+        m_pSimpleTypeArray->populateEnvXPath(strXPath);
+}
+
+void CAttribute::loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+{
+    assert(this->getEnvXPath() != NULL);
+    assert(this->getConstParentNode()->getEnvXPath() != NULL);
+
+    StringBuffer strXPath(this->getConstParentNode()->getEnvXPath());
+
+    if (pEnvTree->hasProp(strXPath.str()) == true)
+    {
+        StringBuffer strAttribName("@");
+
+        strAttribName.append(this->getName());
+        this->setEnvValueFromXML(pEnvTree->queryPropTree(strXPath.str())->queryProp(strAttribName.str()));
+        setInstanceAsValid();
+
+        if (this->m_pSimpleTypeArray != NULL)
+            m_pSimpleTypeArray->loadXMLFromEnvXml(pEnvTree);
+    }
+    else if (stricmp(this->getUse(), XML_ENV_VALUE_REQUIRED) == 0) // check if this a required attribute
+    {
+        assert(false);  // required value missing
+        throw MakeExceptionFromMap(EX_STR_MISSING_REQUIRED_ATTRIBUTE);
+    }
+}
+
+bool CAttribute::setEnvValueFromXML(const char *p)
+{
+    if (p == NULL)
+    {
+        if (this->getDefault() != NULL && *(this->getDefault()) != 0)
+        {
+            this->setInstanceValue(this->getDefault());
+            this->setInstanceAsValid(true);
+            return true;
+        }
+
+        if (this->getUse() != NULL && stricmp(this->getUse(), TAG_REQUIRED) != 0)
+            return true;
+        else
+        {
+            this->setInstanceAsValid(false);
+            //assert (!"Missing attribute property, property not marked as optional");
+
+            return false;
+        }
+    }
+
+    if (this->getTypeNode() != NULL)
+    {
+        const CXSDBuiltInDataType *pNodeBuiltInType = dynamic_cast<const CXSDBuiltInDataType*>(this->getTypeNode());
+
+        if (pNodeBuiltInType != NULL && pNodeBuiltInType->checkConstraint(p) == false)
+        {
+            this->setInstanceAsValid(false);
+            //assert (!"Invalid value for data type");
+
+            return false;
+        }
+
+        if (this->getTypeNode()->getNodeType() == XSD_SIMPLE_TYPE)
+            const CSimpleType *pNodeSimpleType = dynamic_cast<const CSimpleType*>(this->getTypeNode());
+    }
+    if (this->m_ReverseKeyRefArray.length() > 0)
+    {
+        for (int idx = 0; this->m_ReverseKeyRefArray.length(); idx++)
+        {
+           CKeyRef *pKeyRef = static_cast<CKeyRef*>((this->m_ReverseKeyRefArray.item(idx)));
+            assert(pKeyRef != NULL);
+
+            if (pKeyRef->checkConstraint(p) == false)
+            {
+                this->setInstanceAsValid(false);
+                assert (!"Constraint Violated");
+
+                return false;
+            }
+        }
+    }
+    this->setInstanceValue(p);
+    this->setInstanceAsValid(true);
+
+    return true;
+}
+
+void CAttribute::appendReverseKeyRef(const CKeyRef *pKeyRef)
+{
+    assert(pKeyRef != NULL);
+
+    if (pKeyRef != NULL)
+        this->m_ReverseKeyRefArray.append(static_cast<void*>(const_cast<CKeyRef*>(pKeyRef)));
+}
+
+void CAttribute::appendReverseKey(const CKey *pKey)
+{
+    assert(pKey != NULL);
+
+    if (pKey != NULL)
+        this->m_ReverseKeyArray.append(static_cast<void*>(const_cast<CKey*>(pKey)));
+}
+
+CAttribute* CAttribute::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+
+    if (pSchemaRoot == NULL)
+        return NULL;
+
+    CAttribute *pAttribute = new CAttribute(pParentNode);
+
+    pAttribute->setXSDXPath(xpath);
+
+    Owned<IAttributeIterator> iterAttrib = pSchemaRoot->queryPropTree(xpath)->getAttributes(true);
+
+    ForEach(*iterAttrib)
+    {
+        if (strcmp(iterAttrib->queryName(), XML_ATTR_NAME) == 0)
+            pAttribute->setName(iterAttrib->queryValue());
+        else if (strcmp(iterAttrib->queryName(), XML_ATTR_DEFAULT) == 0)
+            pAttribute->setDefault(iterAttrib->queryValue());
+        else if (strcmp(iterAttrib->queryName(), XML_ATTR_USE) == 0)
+            pAttribute->setUse(iterAttrib->queryValue());
+        else if (strcmp(iterAttrib->queryName(), XML_ATTR_TYPE) == 0)
+        {
+            const char *pType = iterAttrib->queryValue();
+            assert(pType != NULL && *pType != 0);
+
+            if (pType != NULL && *pType != 0)
+            {
+                pAttribute->setType(pType);
+                CConfigSchemaHelper::getInstance()->addNodeForTypeProcessing(pAttribute);
+            }
+        }
+    }
+
+
+    StringBuffer strXPathExt(xpath);
+    strXPathExt.append("/").append(XSD_TAG_ANNOTATION);
+
+    CAnnotation *pAnnotation = CAnnotation::load(pAttribute, pSchemaRoot, strXPathExt.str());
+    if (pAnnotation != NULL)
+        pAttribute->setAnnotation(pAnnotation);
+
+    strXPathExt.clear().append(xpath);
+    strXPathExt.append("/").append(XSD_TAG_SIMPLE_TYPE);
+
+    CSimpleTypeArray *pSimpleTypeArray = CSimpleTypeArray::load(pAttribute, pSchemaRoot, strXPathExt.str());
+    if (pSimpleTypeArray != NULL)
+        pAttribute->setSimpleTypeArray(pSimpleTypeArray);
+
+    return pAttribute;
+}
+
+const char* CAttributeArray::getXML(const char* /*pComponent*/)
+{
+    if (m_strXML.length() == 0)
+    {
+        int length = this->length();
+
+        for (int idx = 0; idx < length; idx++)
+        {
+            CAttribute &Attribute = this->item(idx);
+            m_strXML.append(" ").append(Attribute.getXML(NULL));
+
+            if (idx+1 < length)
+                m_strXML.append("\n");
+        }
+    }
+    return m_strXML.str();
+}
+
+CAttributeArray* CAttributeArray::load(const char* pSchemaFile)
+{
+    assert(pSchemaFile != NULL);
+
+    if (pSchemaFile == NULL)
+        return NULL;
+
+    Linked<IPropertyTree> pSchemaRoot;
+
+    StringBuffer schemaPath;
+    schemaPath.appendf("%s%s", DEFAULT_SCHEMA_DIRECTORY, pSchemaFile);
+    pSchemaRoot.setown(createPTreeFromXMLFile(schemaPath.str()));
+
+    StringBuffer strXPathExt("./");
+    strXPathExt.append(XSD_TAG_ATTRIBUTE);
+
+    return CAttributeArray::load(NULL, pSchemaRoot, strXPathExt.str());
+}
+
+CAttributeArray* CAttributeArray::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+
+    if (pSchemaRoot == NULL || xpath == NULL)
+        return NULL;
+
+    StringBuffer strXPathExt(xpath);
+    CAttributeArray *pAttribArray = new CAttributeArray(pParentNode);
+    pAttribArray->setXSDXPath(xpath);
+
+    Owned<IPropertyTreeIterator> attributeIter = pSchemaRoot->getElements(xpath, ipt_ordered);
+
+    int count = 1;
+    ForEach(*attributeIter)
+    {
+        strXPathExt.clear().append(xpath).appendf("[%d]",count);
+
+        CAttribute *pAttrib = CAttribute::load(pAttribArray, pSchemaRoot, strXPathExt.str());
+
+        if (pAttrib != NULL)
+            pAttribArray->append(*pAttrib);
+        count++;
+    }
+
+    if (pAttribArray->length() == 0)
+    {
+        delete pAttribArray;
+        return NULL;
+    }
+    return pAttribArray;
+}
+
+void CAttributeArray::dump(::std::ostream &cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_ATTRIBUTE_ARRAY_STR, offset);
+
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QUICK_OUT(cout, EnvXPath,  offset);
+    QUICK_OUT_ARRAY(cout, offset);
+
+    QuickOutFooter(cout, XSD_ATTRIBUTE_ARRAY_STR, offset);
+}
+
+
+void CAttributeArray::getDocumentation(StringBuffer &strDoc) const
+{
+    assert(this->getConstParentNode() != NULL);
+
+    strDoc.append(DM_SECT4_BEGIN);
+
+    if (this->getConstParentNode()->getNodeType() == XSD_COMPLEX_TYPE && this->getConstParentNode()->getConstParentNode()->getNodeType() != XSD_COMPLEX_TYPE)
+    {
+        strDoc.appendf("%s%s%s", DM_TITLE_BEGIN, "Attributes", DM_TITLE_END);  // Attributes is hard coded default
+        DEBUG_MARK_STRDOC;
+    }
+    else
+    {
+        strDoc.append(DM_TITLE_BEGIN).append(DM_TITLE_END);
+        DEBUG_MARK_STRDOC;
+    }
+
+    const CComplexType *pParentComplexType = dynamic_cast<const CComplexType*>(this->getConstParentNode());
+    const CAttributeGroup *pParentAttributeGroup = dynamic_cast<const CAttributeGroup*>(this->getConstParentNode());
+
+    strDoc.append(DM_TABLE_BEGIN);
+    DEBUG_MARK_STRDOC;
+    strDoc.append(DM_TABLE_ID_BEGIN);
+    DEBUG_MARK_STRDOC;
+
+    if (pParentComplexType != NULL && pParentComplexType->getAnnotation() != NULL && pParentComplexType->getAnnotation()->getAppInfo() != NULL && pParentComplexType->getAnnotation()->getAppInfo()->getDocTableID() != NULL)
+    {
+        strDoc.append(pParentComplexType->getAnnotation()->getAppInfo()->getDocTableID());
+        DEBUG_MARK_STRDOC;
+    }
+    else if  (pParentAttributeGroup != NULL && pParentAttributeGroup->getAnnotation() != NULL && pParentAttributeGroup->getAnnotation()->getAppInfo() != NULL && pParentAttributeGroup->getAnnotation()->getAppInfo()->getDocTableID() != NULL)
+    {
+        strDoc.append(pParentAttributeGroup->getAnnotation()->getAppInfo()->getDocTableID());
+        DEBUG_MARK_STRDOC;
+    }
+    else
+    {
+        static unsigned undefined_counter = 1;
+        strDoc.append(DM_TABLE_ID_UNDEFINED).append("-").append(undefined_counter++);
+        DEBUG_MARK_STRDOC;
+    }
+
+    strDoc.append(DM_TABLE_ID_END);
+    DEBUG_MARK_STRDOC;
+
+    strDoc.append(DM_TGROUP4_BEGIN);
+    strDoc.append(DM_COL_SPEC4);
+    strDoc.append(DM_TBODY_BEGIN);
+
+    DEBUG_MARK_STRDOC;
+    QUICK_DOC_ARRAY(strDoc);
+    DEBUG_MARK_STRDOC;
+
+    strDoc.append(DM_TBODY_END);
+    strDoc.append(DM_TGROUP4_END);
+    strDoc.append(DM_TABLE_END);
+
+    strDoc.append(DM_SECT4_END);
+}
+
+void CAttributeArray::getJSON(StringBuffer &strJSON, unsigned int offset, int idx ) const
+{
+    offset += STANDARD_OFFSET_2;
+
+    int lidx=0;
+
+    for (lidx=0; lidx < this->length(); lidx++)
+    {
+        QuickOutPad(strJSON, offset);
+        strJSON.append("{");
+        (this->item(lidx)).getJSON(strJSON, offset, lidx);
+
+        if (lidx >= 0 && this->length() > 1 && lidx+1 < this->length())
+        {
+            strJSON.append("},\n");
+        }
+    }
+    strJSON.append("}");
+    offset -= STANDARD_OFFSET_2;
+}
+
+void CAttributeArray::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    this->setEnvXPath(strXPath);
+    QUICK_ENV_XPATH_WITH_INDEX(strXPath, index)
+}
+
+void CAttributeArray::loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+{
+    assert(pEnvTree != NULL);
+
+    if (pEnvTree->hasProp(this->getEnvXPath()) == false)
+        throw MakeExceptionFromMap(EX_STR_XPATH_DOES_NOT_EXIST_IN_TREE);
+    else
+    {
+        try
+        {
+            QUICK_LOAD_ENV_XML(pEnvTree)
+        }
+        catch (IException *e)
+        {
+            if (e->errorCode() == EX_STR_MISSING_REQUIRED_ATTRIBUTE)
+                throw e;
+        }
+    }
+}
+
+const CAttribute* CAttributeArray::findAttributeWithName(const char *pName, bool bCaseInsensitive) const
+{
+    assert (pName != NULL && pName[0] != 0);
+    if (pName == NULL || pName[0] == 0 || this->length() == 0)
+        return NULL;
+
+    for (int idx = 0; idx < this->length(); idx++)
+    {
+        if (bCaseInsensitive == true)
+        {
+            if (stricmp(this->item(idx).getName(), pName) == 0)
+                return &(this->item(idx));
+        }
+        else
+        {
+            if (strcmp(this->item(idx).getName(), pName) == 0)
+                return &(this->item(idx));
+        }
+    }
+    return NULL;
+}
+const void CAttributeArray::getAttributeNames(StringArray &names, StringArray &titles) const
+{
+    for(int i = 0; i < this->length(); i++)
+    {
+        if(!this->item(i).isHidden())
+        {
+            names.append(this->item(i).getName());
+            titles.append(this->item(i).getTitle());
+        }
+    }
+}
+
+bool CAttributeArray::getCountOfValueMatches(const char *pValue) const
+{
+    return false;
+}

+ 148 - 0
configuration/configurator/SchemaAttributes.hpp

@@ -0,0 +1,148 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_ATTRIBUTES_HPP_
+#define _SCHEMA_ATTRIBUTES_HPP_
+
+#include "jarray.hpp"
+#include "jatomic.hpp"
+#include "XMLTags.h"
+#include "SchemaCommon.hpp"
+#include "SchemaAnnotation.hpp"
+
+namespace CONFIGURATOR
+{
+
+
+class CSimpleTypeArray;
+class CKeyRefArray;
+class CKeyArray;
+class CKey;
+class CKeyRef;
+
+class CAttribute : public CXSDNodeWithType
+{
+public:
+
+    CAttribute(CXSDNodeBase* pParentNode, const char* pName = NULL) : CXSDNodeWithType::CXSDNodeWithType(pParentNode, XSD_ATTRIBUTE), m_strName(pName),
+            m_strDefault(""), m_strUse(""), m_pAnnotation(NULL), m_pSimpleTypeArray(NULL), m_bInstanceValueValid(false)
+    {
+    }
+
+    CAttribute(CXSDNodeBase* pParentNode, const char* pName, const char* pType, const char* pDefault, const char* pUse) : CXSDNodeWithType::CXSDNodeWithType(pParentNode, XSD_ATTRIBUTE), m_strName(pName), m_pAnnotation(NULL),
+            m_strDefault(pDefault), m_strUse(pUse), m_pSimpleTypeArray(NULL), m_bInstanceValueValid(false)
+    {
+    }
+
+    virtual ~CAttribute();
+
+    GETTERSETTER(Name)
+    GETTERSETTER(Default)
+    GETTERSETTER(Use)
+    GETTERSETTER(InstanceValue)
+
+    const CAnnotation* getAnnotation() const
+    {
+        return m_pAnnotation;
+    }
+
+    const char* getTitle() const;
+    virtual const char* getXML(const char* pComponent);
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const;
+    virtual void getJSON(::StringBuffer &strJSON, unsigned int offset = 0, int idx = -1) const;
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+
+    const CSimpleTypeArray* getSimpleTypeArray() const
+    {
+        return m_pSimpleTypeArray;
+    }
+
+    static CAttribute* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath = NULL);
+
+    bool isInstanceValueValid()
+    {
+        return m_bInstanceValueValid;
+    }
+
+    bool isHidden();
+    virtual bool setEnvValueFromXML(const char *p);
+    void appendReverseKey(const CKey *pKey);
+    void appendReverseKeyRef(const CKeyRef *pKeyRef);
+
+protected:
+
+    void setInstanceAsValid(bool bValid = true)
+    {
+        m_bInstanceValueValid = bValid;
+    }
+
+    void setAnnotation(CAnnotation *pAnnotation)
+    {
+        assert(pAnnotation != NULL);  // why would this ever be NULL?
+        m_pAnnotation = pAnnotation;
+    }
+
+    void setSimpleTypeArray(CSimpleTypeArray *pSimpleTypeArray)
+    {
+        assert(pSimpleTypeArray != NULL);  // why would this ever be NULL?
+        m_pSimpleTypeArray = pSimpleTypeArray;
+    }
+
+    CAnnotation *m_pAnnotation;
+    CSimpleTypeArray *m_pSimpleTypeArray;
+    ::PointerArray m_ReverseKeyArray;
+    ::PointerArray m_ReverseKeyRefArray;
+    bool m_bInstanceValueValid;
+
+private:
+
+};
+
+class CAttributeArray : public ::CIArrayOf<CAttribute>, public InterfaceImpl, public CXSDNodeBase
+{
+public:
+
+    CAttributeArray(CXSDNodeBase* pParentNode = NULL) : CXSDNodeBase::CXSDNodeBase(pParentNode, XSD_ATTRIBUTE_ARRAY)
+    {
+    }
+
+    virtual ~CAttributeArray()
+    {
+    }
+
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const;
+    virtual void getJSON(::StringBuffer &strJSON, unsigned int offset = 0, int idx = -1) const;
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+    virtual const char* getXML(const char* /*pComponent*/);
+    const CAttribute* findAttributeWithName(const char *pName, bool bCaseInsensitive = true) const;
+    const void getAttributeNames(::StringArray &names, ::StringArray &titles) const;
+    static CAttributeArray* load(const char* pSchemaFile);
+    static CAttributeArray* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+protected:
+
+    bool getCountOfValueMatches(const char *pValue) const;
+
+private:
+};
+
+}
+#endif // _SCHEMA_ATTRIBUTES_HPP_

+ 134 - 0
configuration/configurator/SchemaChoice.cpp

@@ -0,0 +1,134 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jptree.hpp"
+#include "XMLTags.h"
+#include "SchemaChoice.hpp"
+#include "SchemaElement.hpp"
+#include "DocumentationMarkup.hpp"
+
+using namespace CONFIGURATOR;
+
+#define StringBuffer ::StringBuffer
+#define IPropertyTree ::IPropertyTree
+
+CChoice* CChoice::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+
+    if (pSchemaRoot == NULL || xpath == NULL)
+         return NULL;
+
+    if (pSchemaRoot->queryPropTree(xpath) == NULL)
+        return NULL; // no xs:choice node found
+
+    StringBuffer strXPathExt(xpath);
+    strXPathExt.append("/").append(XSD_TAG_ELEMENT);
+
+    CArrayOfElementArrays *pArrayOfElemArrays = CArrayOfElementArrays::load(NULL, pSchemaRoot, strXPathExt.str());
+    assert(pArrayOfElemArrays);
+
+    if (pArrayOfElemArrays == NULL)
+        return NULL;
+
+    CChoice *pChoice  = new CChoice(pParentNode, pArrayOfElemArrays);
+    assert(pChoice);
+
+    if (pChoice == NULL)
+        return NULL;
+
+    pChoice->setXSDXPath(xpath);
+
+    SETPARENTNODE(pArrayOfElemArrays, pChoice);
+
+    return pChoice;
+}
+
+const char* CChoice::getXML(const char* /*pComponent*/)
+{
+    if (m_strXML.length() == 0)
+        if (m_pArrayOfElementArrays != NULL)
+            m_strXML.append(m_pArrayOfElementArrays->getXML(NULL));
+
+    return m_strXML.str();
+}
+
+void CChoice::dump(::std::ostream &cout, unsigned int offset) const
+{
+    offset += STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_CHOICE_STR, offset);
+
+    QUICK_OUT(cout, ID,         offset);
+    QUICK_OUT(cout ,MinOccurs,  offset);
+    QUICK_OUT(cout, MaxOccurs,  offset);
+    QUICK_OUT(cout, XSDXPath,   offset);
+
+    if (m_pArrayOfElementArrays != NULL)
+        m_pArrayOfElementArrays->dump(cout, offset);
+
+    QuickOutFooter(cout, XSD_CHOICE_STR, offset);
+}
+
+void CChoice::getDocumentation(StringBuffer &strDoc) const
+{
+    if (m_pArrayOfElementArrays != NULL)
+        m_pArrayOfElementArrays->getDocumentation(strDoc);
+}
+
+void CChoice::getJSON(StringBuffer &strJSON, int idx) const
+{
+    // this is really not correct but roxie.xsd is not correct and probably others
+    bool bSkip = true;
+    for (int i = 0; m_pArrayOfElementArrays->length() > i; i++)
+    {
+        if (m_pArrayOfElementArrays->item(i).length() == 0)
+            continue;
+
+        if (bSkip == false)
+        {
+            strJSON.append(",");
+        }
+        bSkip = false;
+
+        m_pArrayOfElementArrays->item(i).getJSON(strJSON);
+    }
+}
+
+void CChoice::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    this->setEnvXPath(strXPath);
+
+    if (m_pArrayOfElementArrays != NULL)
+        m_pArrayOfElementArrays->populateEnvXPath(strXPath);
+}
+
+void CChoice::loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+{
+    assert (pEnvTree != NULL);
+
+    if (m_pArrayOfElementArrays != NULL)
+    {
+        try
+        {
+            m_pArrayOfElementArrays->loadXMLFromEnvXml(pEnvTree);
+        }
+        catch (...)
+        {
+        }
+    }
+}

+ 66 - 0
configuration/configurator/SchemaChoice.hpp

@@ -0,0 +1,66 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_CHOICE_HPP_
+#define _SCHEMA_CHOICE_HPP_
+
+#include "SchemaCommon.hpp"
+#include "jstring.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CArrayOfElementArrays;
+
+class CChoice : public CXSDNode
+{
+public:
+
+    virtual ~CChoice()
+    {
+    }
+
+    GETTERSETTER(MaxOccurs)
+    GETTERSETTER(MinOccurs)
+    GETTERSETTER(ID)
+
+    virtual void dump(::std::ostream &cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const;
+    virtual void getJSON(::StringBuffer &strJSON, int idx = -1) const;
+    virtual const char* getXML(const char* /*pComponent*/);
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+
+    static CChoice* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+protected:
+
+    CChoice(CXSDNodeBase* pParentNode, CArrayOfElementArrays *pArrayOfElemArrays = NULL) : CXSDNode::CXSDNode(pParentNode, XSD_CHOICE), m_pArrayOfElementArrays(pArrayOfElemArrays)
+    {
+    }
+
+    CArrayOfElementArrays *m_pArrayOfElementArrays;
+
+private:
+
+    CChoice() : CXSDNode::CXSDNode(NULL, XSD_CHOICE)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_CHOICE_HPP_

+ 434 - 0
configuration/configurator/SchemaCommon.cpp

@@ -0,0 +1,434 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+
+#include "jregexp.hpp"
+#include "SchemaCommon.hpp"
+#include "ConfigSchemaHelper.hpp"
+#include "SchemaMapManager.hpp"
+
+#include <cstring>
+
+using namespace CONFIGURATOR;
+
+CXSDNodeBase::CXSDNodeBase(CXSDNodeBase* pParentNode, NODE_TYPES eNodeType) : m_pParentNode(pParentNode),  m_eNodeType(eNodeType)
+{
+   assert(eNodeType != XSD_ERROR);
+
+   switch (eNodeType)
+   {
+   case(XSD_ERROR):
+       strcpy(m_pNodeType, XSD_ERROR_STR);
+       break;
+   case(XSD_ANNOTATION):
+       strcpy(m_pNodeType, XSD_ANNOTATION_STR);
+       break;
+   case(XSD_APP_INFO):
+       strcpy(m_pNodeType, XSD_APP_INFO_STR);
+       break;
+   case(XSD_ATTRIBUTE):
+       strcpy(m_pNodeType, XSD_ATTRIBUTE_STR);
+       break;
+   case(XSD_ATTRIBUTE_ARRAY):
+       strcpy(m_pNodeType, XSD_ATTRIBUTE_ARRAY_STR);
+       break;
+   case(XSD_ATTRIBUTE_GROUP):
+       strcpy(m_pNodeType, XSD_ATTRIBUTE_GROUP_STR);
+       break;
+   case(XSD_ATTRIBUTE_GROUP_ARRAY):
+       strcpy(m_pNodeType, XSD_ATTRIBUTE_GROUP_ARRAY_STR);
+       break;
+   case(XSD_CHOICE):
+       strcpy(m_pNodeType, XSD_CHOICE_STR);
+       break;
+   case(XSD_COMPLEX_CONTENT):
+       strcpy(m_pNodeType, XSD_COMPLEX_CONTENT_STR);
+       break;
+   case(XSD_COMPLEX_TYPE):
+       strcpy(m_pNodeType, XSD_COMPLEX_TYPE_STR);
+       break;
+   case(XSD_COMPLEX_TYPE_ARRAY):
+       strcpy(m_pNodeType, XSD_COMPLEX_TYPE_ARRAY_STR);
+       break;
+   case(XSD_DOCUMENTATION):
+       strcpy(m_pNodeType, XSD_DOCUMENTATION_STR);
+       break;
+   case(XSD_ELEMENT):
+       strcpy(m_pNodeType, XSD_ELEMENT_STR);
+       break;
+   case(XSD_ELEMENT_ARRAY):
+       strcpy(m_pNodeType, XSD_ELEMENT_ARRAY_STR);
+       break;
+   case(XSD_ARRAY_OF_ELEMENT_ARRAYS):
+       strcpy(m_pNodeType, XSD_ARRAY_ELEMENT_ARRAY_STR);
+       break;
+   case(XSD_EXTENSION):
+       strcpy(m_pNodeType, XSD_EXTENSION_STR);
+       break;
+   case(XSD_FIELD):
+       strcpy(m_pNodeType, XSD_FIELD_STR);
+       break;
+   case(XSD_FIELD_ARRAY):
+       strcpy(m_pNodeType, XSD_FIELD_ARRAY_STR);
+       break;
+   case(XSD_KEY):
+       strcpy(m_pNodeType, XSD_KEY_STR);
+       break;
+   case(XSD_KEY_ARRAY):
+       strcpy(m_pNodeType, XSD_KEY_ARRAY_STR);
+       break;
+   case(XSD_KEYREF):
+       strcpy(m_pNodeType, XSD_KEYREF_STR);
+       break;
+   case(XSD_KEYREF_ARRAY):
+       strcpy(m_pNodeType, XSD_KEYREF_ARRAY_STR);
+       break;
+   case(XSD_INCLUDE):
+       strcpy(m_pNodeType, XSD_INCLUDE_STR);
+       break;
+   case(XSD_INCLUDE_ARRAY):
+       strcpy(m_pNodeType, XSD_INCLUDE_ARRAY_STR);
+       break;
+   case(XSD_RESTRICTION):
+       strcpy(m_pNodeType, XSD_RESTRICTION_STR);
+       break;
+   case(XSD_SCHEMA):
+       strcpy(m_pNodeType, XSD_SCHEMA_STR);
+       break;
+   case(XSD_SEQUENCE):
+       strcpy(m_pNodeType, XSD_SEQUENCE_STR);
+       break;
+   case(XSD_SIMPLE_TYPE):
+       strcpy(m_pNodeType, XSD_SIMPLE_TYPE_STR);
+       break;
+   case(XSD_SIMPLE_TYPE_ARRAY):
+       strcpy(m_pNodeType, XSD_SIMPLE_TYPE_ARRAY_STR);
+       break;
+   case(XSD_ENUMERATION):
+       strcpy(m_pNodeType, XSD_ENUMERATION_STR);
+       break;
+   case(XSD_ENUMERATION_ARRAY):
+       strcpy(m_pNodeType, XSD_ENUMERATION_ARRAY_STR);
+       break;
+   case(XSD_LENGTH):
+       strcpy(m_pNodeType, XSD_LENGTH_STR);
+       break;
+   case(XSD_FRACTION_DIGITS):
+       strcpy(m_pNodeType, XSD_FRACTION_DIGITS_STR);
+       break;
+   case(XSD_MAX_EXCLUSIVE):
+       strcpy(m_pNodeType, XSD_MAX_EXCLUSIVE_STR);
+       break;
+   case(XSD_MAX_INCLUSIVE):
+       strcpy(m_pNodeType, XSD_MAX_INCLUSIVE_STR);
+       break;
+   case(XSD_MIN_EXCLUSIVE):
+       strcpy(m_pNodeType, XSD_MIN_INCLUSIVE_STR);
+       break;
+   case(XSD_MIN_LENGTH):
+       strcpy(m_pNodeType, XSD_MIN_LENGTH_STR);
+       break;
+   case(XSD_MAX_LENGTH):
+       strcpy(m_pNodeType, XSD_MAX_LENGTH_STR);
+       break;
+   case(XSD_PATTERN):
+       strcpy(m_pNodeType, XSD_PATTERN_STR);
+       break;
+   case(XSD_SELECTOR):
+       strcpy(m_pNodeType, XSD_SELECTOR_STR);
+       break;
+   case(XSD_TOTAL_DIGITS):
+       strcpy(m_pNodeType, XSD_TOTAL_DIGITS_STR);
+       break;
+   case(XSD_WHITE_SPACE):
+       strcpy(m_pNodeType, XSD_WHITE_SPACE_STR);
+       break;
+   case(XSD_DT_NORMALIZED_STRING):
+       strcpy(m_pNodeType, XSD_DATA_TYPE_NORMALIZED_STRING);
+       break;
+   case(XSD_DT_STRING):
+       strcpy(m_pNodeType, XSD_DATA_TYPE_STRING);
+       break;
+   case(XSD_DT_TOKEN):
+       strcpy(m_pNodeType, XSD_DATA_TYPE_TOKEN);
+       break;
+   case(XSD_DT_DATE):
+       strcpy(m_pNodeType, XSD_DATA_TYPE_DATE);
+       break;
+   case(XSD_DT_TIME):
+       strcpy(m_pNodeType, XSD_DATA_TYPE_TIME);
+       break;
+   case(XSD_DT_DATE_TIME):
+       strcpy(m_pNodeType, XSD_DATA_TYPE_DATE_TIME);
+       break;
+   case(XSD_DT_DECIMAL):
+       strcpy(m_pNodeType, XSD_DATA_TYPE_DECIMAL);
+       break;
+   case(XSD_DT_INT):
+       strcpy(m_pNodeType, XSD_DATA_TYPE_INT);
+       break;
+   case(XSD_DT_INTEGER):
+       strcpy(m_pNodeType, XSD_DATA_TYPE_INTEGER);
+       break;
+   case(XSD_DT_LONG):
+       strcpy(m_pNodeType, XSD_DATA_TYPE_LONG);
+       break;
+   case(XSD_DT_NON_NEG_INTEGER):
+       strcpy(m_pNodeType, XSD_DATA_TYPE_NON_NEGATIVE_INTEGER);
+       break;
+   case(XSD_DT_NON_POS_INTEGER):
+       strcpy(m_pNodeType, XSD_DATA_TYPE_NON_POSITIVE_INTEGER);
+       break;
+   case(XSD_DT_NEG_INTEGER):
+       strcpy(m_pNodeType, XSD_DATA_TYPE_NEGATIVE_INTEGER);
+       break;
+   case(XSD_DT_POS_INTEGER):
+       strcpy(m_pNodeType, XSD_DATA_TYPE_POSITIVE_INTEGER);
+       break;
+   case(XSD_DT_BOOLEAN):
+       strcpy(m_pNodeType, XSD_DATA_TYPE_BOOLEAN);
+       break;
+   default:
+       assert(!"Unknown XSD Type"); // should never get here
+       strcpy(m_pNodeType, XSD_ERROR_STR);
+       break;
+   }
+}
+
+CXSDNodeBase::~CXSDNodeBase()
+{
+}
+
+void CXSDNodeBase::dumpStdOut() const
+{
+   dump(::std::cout);
+}
+
+const CXSDNodeBase* CXSDNodeBase::getConstAncestorNode(unsigned iLevel) const
+{
+   CXSDNodeBase *pAncestorNode = const_cast<CXSDNodeBase*>(this);
+
+   if (iLevel == 0)
+       return this;
+
+   do
+   {
+       pAncestorNode = const_cast<CXSDNodeBase*>(pAncestorNode->getConstParentNode());
+       iLevel--;
+   } while (iLevel > 0 && pAncestorNode != NULL);
+
+   return pAncestorNode;
+}
+
+const CXSDNodeBase* CXSDNodeBase::getParentNodeByType(NODE_TYPES eNodeType[], const CXSDNodeBase *pParent, int length) const
+{
+   for (int i = 0; i < length; i++)
+   {
+       if (this->m_eNodeType == eNodeType[i] && pParent != NULL)
+           return this;
+   }
+   if (this->getConstParentNode() != NULL)
+       return this->getConstParentNode()->getParentNodeByType(eNodeType, this, length);
+
+   return NULL;
+}
+
+CXSDNode::CXSDNode(CXSDNodeBase *pParentNode, NODE_TYPES pNodeType) : CXSDNodeBase::CXSDNodeBase(pParentNode, pNodeType)
+{
+}
+
+bool CXSDNode::checkSelf(NODE_TYPES eNodeType, const char *pName, const char* pCompName) const
+{
+  if (eNodeType & this->getNodeType() && (pName != NULL ? !strcmp(pName, this->getNodeTypeStr()) : true))
+  {
+      assert(pName != NULL); // for now pName should always be populated
+      return this;
+  }
+  return NULL;
+}
+
+const CXSDNodeBase* CXSDNode::getParentNodeByType(NODE_TYPES eNodeType) const
+{
+  if (this->m_eNodeType == eNodeType)
+      return this;
+  if (this->getConstParentNode() != NULL)
+      return this->getConstParentNode()->getParentNodeByType(eNodeType);
+  return NULL;
+}
+
+const CXSDNodeBase* CXSDNodeBase::getNodeByTypeAndNameAscending(NODE_TYPES eNodeType[], const char *pName, int length) const
+{
+  for (int i = 0; i < length; i++)
+  {
+    assert(this->m_eNodeType != eNodeType[i]);
+
+    if (this->getConstParentNode() != NULL)
+        return this->getConstParentNode()->getNodeByTypeAndNameAscending(eNodeType[i], pName);
+  }
+  return NULL;
+}
+
+const CXSDNodeBase* CXSDNodeBase::getNodeByTypeAndNameDescending(NODE_TYPES eNodeType[], const char *pName, int length) const
+{
+    assert(false);  // Derived classes need to hande this
+    return NULL;
+}
+
+const CXSDNodeBase* CXSDNodeBase::getParentNodeByType(NODE_TYPES eNodeType, const CXSDNodeBase *pParent) const
+{
+    if (this->getConstParentNode() == NULL)
+        return NULL;
+    else if (this->getConstParentNode()->getNodeType() == eNodeType)
+        return this->getConstParentNode();
+    else
+        return this->getConstParentNode()->getParentNodeByType(eNodeType, pParent);
+}
+
+CXSDBuiltInDataType* CXSDBuiltInDataType::create(CXSDNodeBase* pParentNode, const char* pNodeType)
+{
+    assert(pParentNode != NULL);
+
+    enum NODE_TYPES eNodeType = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getEnumFromTypeName(pNodeType);
+
+    if (eNodeType != XSD_ERROR)
+        return new CXSDBuiltInDataType(pParentNode, eNodeType);
+    else
+        return NULL;
+}
+
+CXSDBuiltInDataType::CXSDBuiltInDataType(CXSDNodeBase* pParentNode, enum NODE_TYPES eNodeType) : CXSDNode::CXSDNode(pParentNode, eNodeType)
+{
+    assert(eNodeType != XSD_ERROR);
+}
+
+CXSDBuiltInDataType::~CXSDBuiltInDataType()
+{
+}
+
+void CXSDBuiltInDataType::loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree)
+{
+    if (this->getNodeType() == XSD_DT_STRING)
+    {
+
+    }
+}
+
+void CXSDBuiltInDataType::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset += STANDARD_OFFSET_1;
+
+    const char *pTypeNameString = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getTypeNameFromEnum(this->getNodeType(), true);
+
+    QuickOutHeader(cout, pTypeNameString, offset);
+    QuickOutFooter(cout, pTypeNameString, offset);
+}
+
+void CXSDBuiltInDataType::getDocumentation(StringBuffer &strDoc) const
+{
+    UNIMPLEMENTED;
+}
+
+bool CXSDBuiltInDataType::checkConstraint(const char *pValue) const
+{
+    if (pValue == NULL || *pValue == 0)
+        return true;
+
+    enum NODE_TYPES eNodeType = this->getNodeType();
+
+    if (eNodeType >= XSD_DT_NORMALIZED_STRING && eNodeType < XSD_ERROR)
+    {
+        if (XSD_DT_NORMALIZED_STRING == eNodeType)
+        {
+            const char key[] = "\n\r\t";
+            if (strpbrk(pValue, key) != NULL)
+                return false;
+        }
+        else if (XSD_DT_STRING == eNodeType)
+        {
+            // all allowed
+        }
+        else if(XSD_DT_TOKEN == eNodeType)
+        {
+            const char key[] = "\n\r\t";
+            if (strpbrk(pValue, key) != NULL)
+                return false;
+            if (pValue[0] == ' ' || pValue[strlen(pValue)-1] == ' ' || strstr(pValue, "  ")); // leading/trailing space multiple spaces
+                return false;
+        }
+        else if(XSD_DT_DATE == eNodeType)
+        {
+            UNIMPLEMENTED;
+        }
+        else if(XSD_DT_TIME == eNodeType)
+        {
+            UNIMPLEMENTED;
+        }
+        else if(XSD_DT_DATE_TIME == eNodeType)
+        {
+            UNIMPLEMENTED;
+        }
+        else if(XSD_DT_DECIMAL == eNodeType)
+        {
+            UNIMPLEMENTED;
+        }
+        else if(XSD_DT_INT == eNodeType)
+        {
+            UNIMPLEMENTED;
+        }
+        else if(XSD_DT_INTEGER == eNodeType)
+        {
+            RegExpr expr("^(\\+|-)?\\d+$");
+
+            if ((expr.find(pValue)) && (expr.findlen(0) == strlen(pValue)) == false)
+                return false;
+        }
+        else if(XSD_DT_LONG == eNodeType)
+        {
+            UNIMPLEMENTED;
+        }
+        else if(XSD_DT_NON_NEG_INTEGER == eNodeType)
+        {
+            RegExpr expr("^\\d+$");
+
+            if ((expr.find(pValue)) && (expr.findlen(0) == strlen(pValue)) == false)
+                return false;
+        }
+        else if(XSD_DT_NON_POS_INTEGER == eNodeType)
+        {
+            RegExpr expr("^\\d-$");
+
+            if ((expr.find(pValue)) && (expr.findlen(0) == strlen(pValue)) == false)
+                return false;
+        }
+        else if(XSD_DT_NEG_INTEGER == eNodeType)
+        {
+            UNIMPLEMENTED;
+        }
+        else if(XSD_DT_POS_INTEGER == eNodeType)
+        {
+            UNIMPLEMENTED;
+        }
+        else if(XSD_DT_BOOLEAN == eNodeType)
+        {
+            if (stricmp(pValue,"true") != 0 && stricmp(pValue,"false") != 0)
+                return false;
+            else
+                assert("!Unknown datatype");
+        }
+    }
+    return true;
+}

+ 682 - 0
configuration/configurator/SchemaCommon.hpp

@@ -0,0 +1,682 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_COMMON_HPP_
+#define _SCHEMA_COMMON_HPP_
+
+#include <iostream>
+#include "jiface.hpp"
+#include "jstring.hpp"
+#include "jlib.hpp"
+#include "jlog.hpp"
+#include "jarray.hpp"
+#include "XMLTags.h"
+#include "ExceptionStrings.hpp"
+
+namespace CONFIGURATOR
+{
+
+#define MINIMUM_STRICTNESS  0
+#define DEFAULT_STRICTNESS  5
+#define MAXIMUM_STRICTNESS  10
+#define STRICTNESS_LEVEL MINIMUM_STRICTNESS
+
+#define QUICK_OUT(X,Y,Z) QuickOut(X,#Y,get##Y(),Z);
+#define QUICK_OUT_2(Y) QuickOut(cout, #Y, get##Y(), offset);
+#define QUICK_OUT_3(X) if (m_p##X != NULL) m_p##X->dump(cout, offset);
+#define QUICK_OUT_ARRAY(X,Z) for (int idx=0; idx < this->length(); idx++)               \
+                             {                                                          \
+                                QuickOutPad(X,Z+STANDARD_OFFSET_1);                     \
+                                X << idx+1 << "]" << ::std::endl;                         \
+                                (this->item(idx)).dump(cout,Z);                         \
+                             }
+
+#define QUICK_DOC_ARRAY(X) for (int idx=0; idx < this->length(); idx++)                 \
+                           {                                                            \
+                                (this->item(idx)).getDocumentation(X);                  \
+                           }
+#define LAST_ONLY -1
+#define LAST_AND_FIRST  -2
+
+#define QUICK_ENV_XPATH(X) for (int idx=0; idx < this->length(); idx++)                 \
+                            {                                                           \
+                                 (this->item(idx)).populateEnvXPath(X.str(), idx+1);    \
+                            }
+#define QUICK_ENV_XPATH_WITH_INDEX(X,Y) for (int idx=0; idx < this->length(); idx++)    \
+                            {                                                           \
+                                 (this->item(idx)).populateEnvXPath(X.str(), Y);        \
+                            }
+
+#define QUICK_LOAD_ENV_XML(X)   assert(X != NULL);                                      \
+                                for (int idx=0; idx < this->length(); idx++)            \
+                                {                                                       \
+                                     (this->item(idx)).loadXMLFromEnvXml(X);            \
+                                }
+
+#define GETTER(X) virtual const char* get##X() const { return m_str##X.str(); }
+#define SETTER(X) virtual void set##X(const char* p) { m_str##X.clear().append(p); }
+#define GETTERSETTER(X) protected: StringBuffer m_str##X; public: GETTER(X) SETTER(X) public:
+
+//#define GETTER2(X) virtual const char* get##X() const { return m_str##X.str(); }
+//#define SETTER2(X) virtual void set##X(const char* p) { m_str##X.clear().append(p); m_str##X.replace('/','_');}
+//#define GETTERSETTER2(X) protected: StringBuffer m_str##X; public: GETTER(X) SETTER2(X) public:
+
+#define GETTERINT(X) virtual const long get##X() const { return m_n##X; }
+#define SETTERINT(X) virtual void set##X(long p) { m_n##X = p; } virtual void set##X(const char *p) { assert(p != NULL); if (p != 0 && *p != 0) m_n##X = atol(p); }
+#define GETTERSETTERINT(X) protected: long m_n##X; public: GETTERINT(X) SETTERINT(X) private:
+
+#define SETPARENTNODE(X, Y) if (X!= NULL && Y != NULL) X->setParentNode(Y);
+//#define DEBUG_MARK_STRDOC strDoc.append(__FILE__).append(":").append(__LINE__).append("\n");
+#define DEBUG_MARK_STRDOC
+#define DEBUG_MARK_COMMENT(X) X.append("//  ").append(__FILE__).append(":").append(__LINE__).append("\n");
+#define DEBUG_MARK_COMMENT2(X,Y) X.append("//  UIType=").append(Y->getUIType()).append("  ").append(__FILE__).append(":").append(__LINE__).append("\n");
+#define DEBUG_MARK_COMMENT_3 QuickOutPad(strJSON, offset); strJSON.append("{ \"").append(__FILE__).append("\" : \"").append(__LINE__).append("\"},\n"); QuickOutPad(strJSON, offset);
+#define DEBUG_MARK_COMMENT_4 QuickOutPad(strJSON, offset); strJSON.append(",{ \"").append(__FILE__).append("\" : \"").append(__LINE__).append("\"},\n"); QuickOutPad(strJSON, offset);
+#define DEBUG_MARK_STRJS DEBUG_MARK_COMMENT(strJS)
+#define DEBUG_MARK_JSON_1 //DEBUG_MARK_COMMENT_4// DEBUG_MARK_COMMENT(strJSON)
+#define DEBUG_MARK_JSON_2 //DEBUG_MARK_COMMENT_3// DEBUG_MARK_COMMENT(strJSON)
+
+#define GETTERTYPE(X) C##X* get##X() const { return m_p##X; }
+#define SETTERTYPE(X) void set##X( C##X *p ) { assert(p != NULL); if (p != NULL) m_p##X = p; }
+#define GETTERSETTERTYPE(X) public: C##X *m_p##X; GETTERTYPE(X) SETTERTYPE(X) private:
+
+#define CHECK_EXCLUSION(X)  if(CConfigSchemaHelper::getInstance()->getSchemaMapManager()->isNodeExcluded(X)) return nullptr;
+#define IS_EXCLUDED(X)      (CConfigSchemaHelper::getInstance()->getSchemaMapManager()->isNodeExcluded(X) ? true : false)
+
+enum NODE_TYPES
+{
+    XSD_ANNOTATION = 0x0,
+    XSD_APP_INFO,
+    XSD_ATTRIBUTE,
+    XSD_ATTRIBUTE_ARRAY,
+    XSD_ATTRIBUTE_GROUP,
+    XSD_ATTRIBUTE_GROUP_ARRAY,
+    XSD_CHOICE,
+    XSD_COMPLEX_CONTENT,
+    XSD_COMPLEX_TYPE,
+    XSD_COMPLEX_TYPE_ARRAY,
+    XSD_DOCUMENTATION,
+    XSD_ELEMENT,
+    XSD_ELEMENT_ARRAY,
+    XSD_ARRAY_OF_ELEMENT_ARRAYS,
+    XSD_EXTENSION,
+    XSD_FIELD,
+    XSD_FIELD_ARRAY,
+    XSD_KEY,
+    XSD_KEY_ARRAY,
+    XSD_KEYREF,
+    XSD_KEYREF_ARRAY,
+    XSD_INCLUDE,
+    XSD_INCLUDE_ARRAY,
+    XSD_RESTRICTION,
+    XSD_SCHEMA,
+    XSD_SEQUENCE,
+    XSD_SIMPLE_TYPE,
+    XSD_SIMPLE_TYPE_ARRAY,
+    XSD_ENUMERATION,
+    XSD_ENUMERATION_ARRAY,
+    XSD_LENGTH,
+    XSD_FRACTION_DIGITS,
+    XSD_MAX_EXCLUSIVE,
+    XSD_MAX_INCLUSIVE,
+    XSD_MIN_EXCLUSIVE,
+    XSD_MIN_INCLUSIVE,
+    XSD_MIN_LENGTH,
+    XSD_MAX_LENGTH,
+    XSD_PATTERN,
+    XSD_SELECTOR,
+    XSD_SIMPLE_CONTENT,
+    XSD_TOTAL_DIGITS,
+    XSD_UNIQUE,
+    XSD_UNIQUE_ARRAY,
+    XSD_WHITE_SPACE,
+    XSD_DT_NORMALIZED_STRING,  // keep this as the first DT type for array index purposes
+    XSD_DT_STRING,
+    XSD_DT_TOKEN,
+    XSD_DT_DATE,
+    XSD_DT_TIME,
+    XSD_DT_DATE_TIME,
+    XSD_DT_DECIMAL,
+    XSD_DT_INT,
+    XSD_DT_INTEGER,
+    XSD_DT_LONG,
+    XSD_DT_NON_NEG_INTEGER,
+    XSD_DT_NON_POS_INTEGER,
+    XSD_DT_NEG_INTEGER,
+    XSD_DT_POS_INTEGER,
+    XSD_DT_BOOLEAN,
+    XSD_ERROR
+};
+
+static const char* DEFAULT_SCHEMA_DIRECTORY("/opt/HPCCSystems/componentfiles/configxml/");
+
+#define NAME_SPACE_FOR_XSD_SCHEMA   "xs:"
+
+static const char* XSD_TAG_ANNOTATION(NAME_SPACE_FOR_XSD_SCHEMA"annotation");
+static const char* XSD_TAG_APP_INFO(NAME_SPACE_FOR_XSD_SCHEMA"appinfo");
+//static const char* XSD_TAG_ATTRIBUTE(NAME_SPACE_FOR_XSD_SCHEMA"attribute");
+//static const char* XSD_TAG_ATTRIBUTE_GROUP(NAME_SPACE_FOR_XSD_SCHEMA"attributeGroup");
+//static const char* XSD_TAG_CHOICE(NAME_SPACE_FOR_XSD_SCHEMA"choice");
+//static const char* XSD_TAG_COMPLEX_CONTENT(NAME_SPACE_FOR_XSD_SCHEMA"complexContent");
+//static const char* XSD_TAG_COMPLEX_TYPE(NAME_SPACE_FOR_XSD_SCHEMA"complexType");
+static const char* XSD_TAG_DOCUMENTATION(NAME_SPACE_FOR_XSD_SCHEMA"documentation");
+//static const char* XSD_TAG_ELEMENT(NAME_SPACE_FOR_XSD_SCHEMA"element");
+static const char* XSD_TAG_EXTENSION(NAME_SPACE_FOR_XSD_SCHEMA"extension");
+static const char* XSD_TAG_KEY(NAME_SPACE_FOR_XSD_SCHEMA"key");
+static const char* XSD_TAG_KEYREF(NAME_SPACE_FOR_XSD_SCHEMA"keyref");
+static const char* XSD_TAG_SELECTOR(NAME_SPACE_FOR_XSD_SCHEMA"selector");
+static const char* XSD_TAG_FIELD(NAME_SPACE_FOR_XSD_SCHEMA"field");
+static const char* XSD_TAG_INCLUDE(NAME_SPACE_FOR_XSD_SCHEMA"include");
+static const char* XSD_TAG_RESTRICTION(NAME_SPACE_FOR_XSD_SCHEMA"restriction");
+static const char* XSD_TAG_SCHEMA("");
+static const char* XSD_TAG_SIMPLE_CONTENT(NAME_SPACE_FOR_XSD_SCHEMA"simpleContent");
+//static const char* XSD_TAG_SEQUENCE(NAME_SPACE_FOR_XSD_SCHEMA"sequence");
+static const char* XSD_TAG_SIMPLE_TYPE(NAME_SPACE_FOR_XSD_SCHEMA"simpleType");
+static const char* XSD_TAG_ENUMERATION(NAME_SPACE_FOR_XSD_SCHEMA"enumeration");
+static const char* XSD_TAG_FRACTION_DIGITS(NAME_SPACE_FOR_XSD_SCHEMA"fractionDigits");
+static const char* XSD_TAG_LENGTH(NAME_SPACE_FOR_XSD_SCHEMA"length");
+static const char* XSD_TAG_MAX_EXCLUSIVE(NAME_SPACE_FOR_XSD_SCHEMA"maxExclusive");
+static const char* XSD_TAG_MAX_INCLUSIVE(NAME_SPACE_FOR_XSD_SCHEMA"maxInclusive");
+static const char* XSD_TAG_MIN_EXCLUSIVE(NAME_SPACE_FOR_XSD_SCHEMA"minExlusive");
+static const char* XSD_TAG_MIN_INCLUSIVE(NAME_SPACE_FOR_XSD_SCHEMA"minExclusive");
+static const char* XSD_TAG_MAX_LENGTH(NAME_SPACE_FOR_XSD_SCHEMA"maxLength");
+static const char* XSD_TAG_MIN_LENGTH(NAME_SPACE_FOR_XSD_SCHEMA"minLength");
+static const char* XSD_TAG_PATTERN(NAME_SPACE_FOR_XSD_SCHEMA"pattern");
+static const char* XSD_TAG_TOTAL_DIGITS(NAME_SPACE_FOR_XSD_SCHEMA"totalDigits");
+static const char* XSD_TAG_UNQIUE(NAME_SPACE_FOR_XSD_SCHEMA"unique");
+static const char* XSD_TAG_WHITE_SPACE(NAME_SPACE_FOR_XSD_SCHEMA"whiteSpace");
+
+static const char* XSD_DATA_TYPE_NORMALIZED_STRING(NAME_SPACE_FOR_XSD_SCHEMA"normalizedString");
+static const char* XSD_DATA_TYPE_STRING(NAME_SPACE_FOR_XSD_SCHEMA"string");
+static const char* XSD_DATA_TYPE_TOKEN(NAME_SPACE_FOR_XSD_SCHEMA"token");
+static const char* XSD_DATA_TYPE_DATE(NAME_SPACE_FOR_XSD_SCHEMA"date");
+static const char* XSD_DATA_TYPE_TIME(NAME_SPACE_FOR_XSD_SCHEMA"time");
+static const char* XSD_DATA_TYPE_DATE_TIME(NAME_SPACE_FOR_XSD_SCHEMA"dateTime");
+static const char* XSD_DATA_TYPE_DECIMAL(NAME_SPACE_FOR_XSD_SCHEMA"decimal"); // A decimal value
+static const char* XSD_DATA_TYPE_INTEGER(NAME_SPACE_FOR_XSD_SCHEMA"integer"); // An integer value
+static const char* XSD_DATA_TYPE_INT(NAME_SPACE_FOR_XSD_SCHEMA"int"); // A signed 32-bit integer
+static const char* XSD_DATA_TYPE_LONG(NAME_SPACE_FOR_XSD_SCHEMA"long"); // A signed 64-bit integer
+static const char* XSD_DATA_TYPE_NON_NEGATIVE_INTEGER(NAME_SPACE_FOR_XSD_SCHEMA"nonNegativeInteger");
+static const char* XSD_DATA_TYPE_NON_POSITIVE_INTEGER(NAME_SPACE_FOR_XSD_SCHEMA"nonPositiveInteger");
+static const char* XSD_DATA_TYPE_NEGATIVE_INTEGER(NAME_SPACE_FOR_XSD_SCHEMA"negativeInteger");
+static const char* XSD_DATA_TYPE_POSITIVE_INTEGER(NAME_SPACE_FOR_XSD_SCHEMA"positiveInteger");
+static const char* XSD_DATA_TYPE_BOOLEAN(NAME_SPACE_FOR_XSD_SCHEMA"boolean");
+
+static const char* XSD_ANNOTATION_STR("Annotation");
+static const char* XSD_APP_INFO_STR("AppInfo");
+static const char* XSD_ATTRIBUTE_STR("Attribute");
+static const char* XSD_ATTRIBUTE_ARRAY_STR("AttributeArray");
+static const char* XSD_ATTRIBUTE_GROUP_STR("AttributeGroup");
+static const char* XSD_ATTRIBUTE_GROUP_ARRAY_STR("AttributeGroupArray");
+static const char* XSD_CHOICE_STR("Choice");
+static const char* XSD_COMPLEX_CONTENT_STR("ComplexContent");
+static const char* XSD_COMPLEX_TYPE_STR("ComplexType");
+static const char* XSD_COMPLEX_TYPE_ARRAY_STR("ComplexTypeArray");
+static const char* XSD_DOCUMENTATION_STR("Documentation");
+static const char* XSD_ELEMENT_STR("Element");
+static const char* XSD_ELEMENT_ARRAY_STR("ElementArray");
+static const char* XSD_ARRAY_ELEMENT_ARRAY_STR("ArrayOfElementArrays");
+static const char* XSD_ERROR_STR("ERROR");
+static const char* XSD_ENUMERATION_STR("Enumeration");
+static const char* XSD_ENUMERATION_ARRAY_STR("EnumerationArray");
+static const char* XSD_EXTENSION_STR("Extension");
+static const char* XSD_FIELD_STR("Field");
+static const char* XSD_FIELD_ARRAY_STR("FieldArray");
+static const char* XSD_FRACTION_DIGITS_STR("FractionDigits");
+static const char* XSD_INCLUDE_STR("Include");
+static const char* XSD_INCLUDE_ARRAY_STR("IncludeArray");
+static const char* XSD_KEY_STR("Key");
+static const char* XSD_KEY_ARRAY_STR("KeyArray");
+static const char* XSD_KEYREF_STR("KeyRef");
+static const char* XSD_KEYREF_ARRAY_STR("KeyRefArray");
+static const char* XSD_LENGTH_STR("Length");
+static const char* XSD_MIN_INCLUSIVE_STR("MinInclusive");
+static const char* XSD_MAX_INCLUSIVE_STR("MaxInclusive");
+static const char* XSD_MIN_EXCLUSIVE_STR("MinExclusive");
+static const char* XSD_MAX_EXCLUSIVE_STR("MaxExclusive");
+static const char* XSD_MIN_LENGTH_STR("MinLength");
+static const char* XSD_MAX_LENGTH_STR("MaxLength");
+static const char* XSD_PATTERN_STR("Pattern");
+static const char* XSD_RESTRICTION_STR("Restriction");
+static const char* XSD_SCHEMA_STR("Schema");
+static const char* XSD_SELECTOR_STR("Selector");
+static const char* XSD_SEQUENCE_STR("Sequence");
+static const char* XSD_SIMPLE_CONTENT_STR("SimpleContent");
+static const char* XSD_SIMPLE_TYPE_STR("SimpleType");
+static const char* XSD_SIMPLE_TYPE_ARRAY_STR("SimpleTypeArray");
+static const char* XSD_TOTAL_DIGITS_STR("TotalDigits");
+static const char* XSD_UNIQUE_STR("Unique");
+static const char* XSD_UNIQUE_ARRAY_STR("UniqueArray");
+static const char* XSD_WHITE_SPACE_STR("WhiteSpace");
+static const char* XSD_DT_NORMALIZED_STRING_STR("NormalizedString");
+static const char* XSD_DT_STRING_STR("String");
+static const char* XSD_DT_TOKEN_STR("Token");
+static const char* XSD_DT_DATE_STR("Date");
+static const char* XSD_DT_TIME_STR("Time");
+static const char* XSD_DT_DATE_TIME_STR("DateTime");
+static const char* XSD_DT_DECIMAL_STR("Decimal");
+static const char* XSD_DT_INTEGER_STR("Integer");
+static const char* XSD_DT_INT_STR("Int");
+static const char* XSD_DT_LONG_STR("Long");
+static const char* XSD_DT_NON_NEG_INTEGER_STR("NonNegativeInteger");
+static const char* XSD_DT_NON_POS_INTEGER_STR("NonPositiveInteger");
+static const char* XSD_DT_POS_INTEGER_STR("PositiveInteger");
+static const char* XSD_DT_NEG_INTEGER_STR("NegativeInteger");
+static const char* XSD_DT_BOOLEAN_STR("Boolean");
+
+static const char* XML_ENV_VALUE_OPTIONAL("optional");
+static const char* XML_ENV_VALUE_REQUIRED("required");
+
+static const char* XML_ATTR_DEFAULT("@default");
+static const char* XML_ATTR_USE("@use");
+static const char* XML_ATTR_MINOCCURS("@minOccurs");
+static const char* XML_ATTR_BASE("@base");
+static const char* XML_ATTR_XPATH("@xpath");
+static const char* XML_ATTR_REFER("@refer");
+
+static const char* TAG_VIEWCHILDNODES("viewChildNodes");
+static const char* TAG_VIEWTYPE("viewType");
+static const char* TAG_TOOLTIP("tooltip");
+static const char* TAG_COLINDEX("colIndex");
+static const char* TAG_TITLE("title");
+static const char* TAG_WIDTH("width");
+static const char* TAG_AUTOGENWIZARD("autogenforwizard");
+static const char* TAG_AUTOGENDEFAULTVALUE("autogendefaultvalue");
+static const char* TAG_AUTOGENDEFAULTVALUEFORMULTINODE("autogendefaultformultinode");
+static const char* TAG_XPATH("xpath");
+static const char* TAG_DOC_ID("docid");
+static const char* TAG_DOC_USE_LINE_BREAK("docuselinebreak");
+static const char* TAG_UNBOUNDED("unbounded");
+
+#define TAG_OPTIONAL                   "optional"
+#define TAG_REQUIRED                   "required"
+#define XML_ATTR_ATTRIBUTEFORMDEFAULT  "@attributeFormDefault"
+#define XML_ATTR_ELEMENTFORMDEFAULT    "@elementFormDefault"
+#define XML_ATTR_ID                    "@id"
+#define XML_ATTR_REF                   "@ref"
+#define XML_ATTR_XMLNS_XS              "@xmlns:xs"
+#define XML_ATTR_SCHEMA_LOCATION       "@schemaLocation"
+#define XML_ATTR_VALUE                 "@value"
+#define XML_ATTR_OVERIDE               "@overide"
+#define XML_ATTR_DEPLOYABLE            "@deployable"
+
+static unsigned int STANDARD_OFFSET_1 = 3;
+static unsigned int STANDARD_OFFSET_2 = 6;
+static unsigned int STANDARD_OFFSET_3 = 9;
+
+static void QuickOutPad(::std::ostream& cout, unsigned int offset)
+{
+    while(offset > 0)
+    {
+        cout << " ";
+        offset--;
+    }
+}
+
+static void QuickOutPad(::StringBuffer &str, unsigned int offset)
+{
+    while(offset > 0)
+    {
+        str.append(" ");
+        offset--;
+    }
+}
+
+static void QuickOutHeader(::std::ostream &cout, const char* pLabel, unsigned int offset = 0)
+{
+    QuickOutPad(cout,offset);
+    cout << "\033[32m-- " << pLabel << " START" << " --" << "\033[0m" << ::std::endl;
+}
+
+static void QuickOutFooter(::std::ostream &cout, const char* pLabel, unsigned int offset = 0)
+{
+    QuickOutPad(cout,offset);
+    //cout << "<--- FINISH " << pLabel << ::std::endl;
+    cout << "\033[31m" << "-- " << pLabel << " FINISH" << " --" << "\033[0m" << ::std::endl;
+}
+
+static void QuickOut(::std::ostream &cout, const char* pLabel, const char* pValue, unsigned int offset = 0)
+{
+    if (pLabel && strlen(pValue) > 0)
+    {
+        QuickOutPad(cout,offset+STANDARD_OFFSET_2);
+        cout << "\033[34m" << pLabel << ":\t\033[0m" << "\033[34m'\033[0m" << pValue << "\033[34m'" << "\033[0m" << ::std::endl;
+    }
+}
+
+static void QuickOut(::std::ostream &cout, const char* pLabel, int value, unsigned int offset = 0)
+{
+    QuickOutPad(cout,offset);
+    cout << pLabel << ": " << value << ::std::endl;
+}
+
+static const char* stripTrailingIndex(StringBuffer& strXPath)  // should this replace int CConfigSchemaHelper::stripXPathIndex(StringBuffer &strXPath)?
+{
+    if (strXPath.length() == 0 || strXPath[strXPath.length()-1] != ']')
+        return strXPath.str();
+
+    while (1)
+    {
+        if (strXPath[strXPath.length()-1] == '[')
+        {
+            strXPath.setLength(strXPath.length()-1);
+            break;
+        }
+        strXPath.setLength(strXPath.length()-1);
+    }
+
+    return strXPath.str();
+}
+
+class InterfaceImpl : public IInterface
+{
+public:
+
+    InterfaceImpl()
+    {
+        atomic_set(&xxcount, 1);
+    }
+
+    virtual void Link() const
+    {
+        atomic_inc(&xxcount);
+    }
+
+    virtual bool Release() const
+    {
+        if (atomic_dec_and_test(&xxcount))
+        {
+           delete this;
+           return true;
+        }
+
+        return false;
+    }
+
+    int getLinkCount() const
+    {
+        return xxcount.counter;
+    }
+
+private:
+
+    mutable atomic_t xxcount;
+};
+
+class CXSDNodeBase
+{
+public:
+
+    CXSDNodeBase(CXSDNodeBase* pParentNode = NULL, NODE_TYPES eNodeType = XSD_ERROR);
+
+    virtual ~CXSDNodeBase();
+
+    GETTERSETTER(XSDXPath)
+    GETTERSETTER(EnvXPath)
+    //GETTERSETTER(EnvValueFromXML)
+    virtual const char* getEnvValueFromXML() const
+    {
+        return m_strEnvValueFromXML;
+    }
+
+    virtual bool setEnvValueFromXML(const char* p)
+    {
+        if (p != NULL)
+        {
+            m_strEnvValueFromXML.set(p);
+            return true;
+        }
+        return false;
+    }
+
+    void dumpStdOut() const;
+
+    virtual CXSDNodeBase* getParentNode() const
+    {
+        return m_pParentNode;
+    }
+
+    virtual const CXSDNodeBase* getConstAncestorNode(unsigned iLevel) const;
+    virtual const CXSDNodeBase* getConstParentNode() const
+    {
+        return m_pParentNode;
+    }
+
+    virtual const CXSDNodeBase* getParentNodeByType(NODE_TYPES eNodeType[], const CXSDNodeBase *pParent = NULL, int length = 1) const;
+    virtual const CXSDNodeBase* getParentNodeByType(NODE_TYPES eNodeType, const CXSDNodeBase *pParent = NULL) const;
+    virtual const CXSDNodeBase* getNodeByTypeAndNameAscending(NODE_TYPES eNodeType[], const char *pName, int length = 1) const;
+    virtual const CXSDNodeBase* getNodeByTypeAndNameAscending(NODE_TYPES eNodeType, const char *pName) const
+    {
+        if (this->getNodeType() == eNodeType)
+            return this;
+        else
+            return this->getConstParentNode()->getNodeByTypeAndNameAscending(eNodeType, pName);
+    }
+    virtual const CXSDNodeBase* getNodeByTypeAndNameDescending(NODE_TYPES eNodeType[], const char *pName, int length = 1) const;
+    virtual const CXSDNodeBase* getNodeByTypeAndNameDescending(NODE_TYPES eNodeType, const char *pName) const
+    {
+        return getNodeByTypeAndNameDescending(&eNodeType, pName);
+    }
+    void setParentNode(CXSDNodeBase *pParentNode)
+    {
+        if (m_pParentNode == NULL)  // Should only be set once, otherwise it's an external schema and should have parent set
+        {
+            m_pParentNode = pParentNode;
+        }
+    }
+    const char* getNodeTypeStr() const
+    {
+        return m_pNodeType;
+    }
+    virtual NODE_TYPES getNodeType() const
+    {
+        return m_eNodeType;
+    }
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const = 0;
+
+    virtual const char* getXML(const char* /*pComponent*/)
+    {
+        return NULL;
+    }
+
+    virtual void getDocumentation(::StringBuffer &strDoc) const = 0;
+
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1)
+    {
+    }
+
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree)
+    {
+    }
+
+protected:
+
+    CXSDNodeBase*               m_pParentNode;
+    ::StringBuffer                m_strXML;
+    NODE_TYPES                  m_eNodeType;
+    char                        m_pNodeType[1024];
+    StringBuffer                m_strEnvValueFromXML;
+
+private:
+
+};
+
+class CXSDNode : public CInterface, public CXSDNodeBase
+{
+public:
+
+    IMPLEMENT_IINTERFACE
+
+    CXSDNode(CXSDNodeBase *pParentNode, NODE_TYPES pNodeType = XSD_ERROR );
+
+    virtual bool checkSelf(NODE_TYPES eNodeType, const char *pName, const char* pCompName) const;
+    virtual const CXSDNodeBase* getParentNodeByType(NODE_TYPES eNodeType) const;
+
+private:
+};
+
+template<class T>
+class CXSDNodeWithRestrictions : public CXSDNode
+{
+
+public:
+
+    CXSDNodeWithRestrictions(CXSDNodeBase* pParentNode, enum NODE_TYPES eNodeType) : CXSDNode::CXSDNode(pParentNode)
+    {
+    }
+
+    static T* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath)
+    {
+        assert(pSchemaRoot != NULL);
+
+        if (pSchemaRoot == NULL)
+            return NULL;
+
+        T *pT = NULL;
+
+        if (xpath != NULL && *xpath != 0)
+        {
+            ::IPropertyTree* pTree = pSchemaRoot->queryPropTree(xpath);
+
+            if (pTree == NULL)
+                return NULL;
+
+            pT = new T(pParentNode);
+
+            const char* pValue = pTree->queryProp(XML_ATTR_VALUE);
+
+            if (pValue != NULL && *pValue != 0)
+                pT->setValue(pValue);
+            else
+            {
+                assert(!"No Value set");
+                //TODO: throw? and delete?
+            }
+            pT->setXSDXPath(xpath);
+        }
+        return pT;
+    }
+
+    void dump(::std::ostream& cout, unsigned int offset) const
+    {
+        offset += STANDARD_OFFSET_1;
+
+        QuickOutHeader(cout, XSD_MIN_INCLUSIVE_STR, offset);
+        QUICK_OUT(cout, Value, offset);
+        QuickOutFooter(cout, XSD_MIN_INCLUSIVE_STR, offset);
+    }
+
+    virtual void getDocumentation(::StringBuffer &strDoc) const
+    {
+        UNIMPLEMENTED;
+    }
+
+    virtual const char* getXML(const char* /*pComponent*/)
+    {
+        UNIMPLEMENTED;
+        return NULL;
+    }
+
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1)
+    {
+        UNIMPLEMENTED;
+    }
+
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree)
+    {
+        UNIMPLEMENTED;
+    }
+
+    GETTERSETTER(Value)
+};
+
+class CXSDNodeWithType : public CXSDNode
+{
+    GETTERSETTER(Type)
+
+public:
+
+    CXSDNodeWithType(CXSDNodeBase* pParentNode, enum NODE_TYPES eNodeType) : CXSDNode::CXSDNode(pParentNode, eNodeType), m_pXSDNode(NULL)
+    {
+    }
+
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree)
+    {
+        UNIMPLEMENTED_X("Should be implemented in the derived class");
+    }
+
+    void setTypeNode(CXSDNode* pCXSDNode)
+    {
+        m_pXSDNode = pCXSDNode;
+    }
+
+    const CXSDNode* getTypeNode() const
+    {
+        return m_pXSDNode;
+    }
+
+protected:
+
+    CXSDNode *m_pXSDNode;
+};
+
+class CXSDNodeWithBase : public CXSDNode
+{
+    GETTERSETTER(Base)
+
+public:
+
+    CXSDNodeWithBase(CXSDNodeBase* pParentNode, enum NODE_TYPES eNodeType) : CXSDNode::CXSDNode(pParentNode, eNodeType), m_pXSDNode(NULL)
+    {
+    }
+
+    void setBaseNode(CXSDNodeBase* pCXSDNode)
+    {
+        m_pXSDNode = pCXSDNode;
+    }
+
+    const CXSDNodeBase* getBaseNode() const
+    {
+        return m_pXSDNode;
+    }
+
+protected:
+
+    CXSDNodeBase *m_pXSDNode;
+};
+
+class CXSDBuiltInDataType : public CXSDNode
+{
+public:
+
+    static CXSDBuiltInDataType* create(CXSDNodeBase* pParentNode, const char* pNodeType);
+
+    virtual ~CXSDBuiltInDataType();
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const;
+    virtual bool checkConstraint(const char *pValue) const;
+
+private:
+
+    CXSDBuiltInDataType(CXSDNodeBase* pParentNode = NULL, NODE_TYPES eNodeType = XSD_ERROR);
+    CXSDBuiltInDataType(CXSDNodeBase* pParentNode, const char* pNodeType);
+};
+
+}
+
+#endif // _SCHEMA_COMMON_HPP_

+ 82 - 0
configuration/configurator/SchemaComplexContent.cpp

@@ -0,0 +1,82 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jptree.hpp"
+#include "XMLTags.h"
+#include "SchemaComplexContent.hpp"
+#include "SchemaExtension.hpp"
+#include "ConfigSchemaHelper.hpp"
+
+using namespace CONFIGURATOR;
+
+#define StringBuffer ::StringBuffer
+#define IPropertyTree ::IPropertyTree
+
+CComplexContent* CComplexContent::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot);
+
+    if (pSchemaRoot == nullptr)
+        return nullptr;
+
+    StringBuffer strXPathExt(xpath);
+    strXPathExt.append("/").append(XSD_TAG_EXTENSION);
+
+    if (pSchemaRoot->queryPropTree(strXPathExt.str()) == nullptr || IS_EXCLUDED(XSD_EXTENSION) == false)
+        return nullptr;
+
+    CExtension* pExtension = CExtension::load(nullptr, pSchemaRoot, strXPathExt.str());
+    CComplexContent *pComplexContent = new CComplexContent(pParentNode, pExtension);
+
+    pComplexContent->setXSDXPath(xpath);
+    assert(pExtension != nullptr);
+
+    assert(pComplexContent != nullptr);
+    if (pExtension != nullptr && pComplexContent != nullptr)
+    {
+        SETPARENTNODE(pExtension, pComplexContent);
+        pExtension->initExtension();
+    }
+    return pComplexContent;
+}
+
+void CComplexContent::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_COMPLEX_CONTENT_STR, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+
+    if (m_pExtension != nullptr)
+        m_pExtension->dump(cout, offset);
+
+    QuickOutFooter(cout, XSD_COMPLEX_CONTENT_STR, offset);
+}
+
+
+void CComplexContent::getDocumentation(StringBuffer &strDoc) const
+{
+    return;
+}
+
+const char* CComplexContent::getXML(const char* /*pComponent*/)
+{
+    if (m_strXML.length() == 0 && m_pExtension != nullptr)
+        m_strXML.append(m_pExtension->getXML(nullptr));
+
+    return m_strXML.str();
+}

+ 58 - 0
configuration/configurator/SchemaComplexContent.hpp

@@ -0,0 +1,58 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_COMPLEX_CONTENT_HPP_
+#define _SCHEMA_COMPLEX_CONTENT_HPP_
+
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CExtension;
+
+class CComplexContent : public CXSDNode
+{
+public:
+
+    virtual ~CComplexContent()
+    {
+    }
+
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const;
+    virtual const char* getXML(const char* /*pComponent*/);
+
+    static CComplexContent* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath = NULL);
+
+protected:
+
+    CComplexContent(CXSDNodeBase* pParentNode, CExtension *pExtension = NULL) : CXSDNode::CXSDNode(pParentNode, XSD_COMPLEX_CONTENT), m_pExtension(pExtension)
+    {
+    }
+
+    CExtension *m_pExtension;
+
+private:
+
+    CComplexContent(CXSDNodeBase* pParentNode = NULL) : CXSDNode::CXSDNode(pParentNode, XSD_COMPLEX_CONTENT)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_COMPLEX_CONTENT_HPP_

+ 443 - 0
configuration/configurator/SchemaComplexType.cpp

@@ -0,0 +1,443 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include <cassert>
+#include "jstring.hpp"
+#include "jptree.hpp"
+#include "XMLTags.h"
+#include "SchemaComplexType.hpp"
+#include "SchemaSequence.hpp"
+#include "SchemaComplexContent.hpp"
+#include "SchemaAttributes.hpp"
+#include "SchemaChoice.hpp"
+#include "SchemaComplexType.hpp"
+#include "SchemaSchema.hpp"
+#include "ConfigSchemaHelper.hpp"
+#include "DocumentationMarkup.hpp"
+#include "ExceptionStrings.hpp"
+#include "SchemaMapManager.hpp"
+#include "JSONMarkUp.hpp"
+
+using namespace CONFIGURATOR;
+
+#define StringBuffer ::StringBuffer
+#define IPropertyTree ::IPropertyTree
+
+const CXSDNodeBase* CComplexType::getNodeByTypeAndNameAscending(NODE_TYPES eNodeType, const char *pName) const
+{
+    const CXSDNodeBase* pMatchingNode = NULL;
+
+    if (eNodeType == this->getNodeType() && (pName != NULL ? !strcmp(pName, this->getNodeTypeStr()) : true))
+        return this;
+
+    if (m_pSequence != NULL)
+        pMatchingNode =  m_pSequence->getNodeByTypeAndNameAscending(eNodeType, pName);
+
+    return pMatchingNode;
+}
+
+const CXSDNodeBase* CComplexType::getNodeByTypeAndNameDescending(NODE_TYPES eNodeType, const char *pName) const
+{
+    const CXSDNodeBase* pMatchingNode = NULL;
+
+    if (eNodeType == this->getNodeType() && (pName != NULL ? !strcmp(pName, this->getNodeTypeStr()) : true))
+        return this;
+
+    if (m_pSequence != NULL)
+        pMatchingNode = m_pSequence->getNodeByTypeAndNameDescending(eNodeType, pName);
+    if (pMatchingNode == NULL && m_pSequence != NULL)
+        pMatchingNode = m_pComplexContent->getNodeByTypeAndNameDescending(eNodeType, pName);
+    if (pMatchingNode == NULL && m_pAttributeArray != NULL)
+        pMatchingNode = m_pSequence->getNodeByTypeAndNameDescending(eNodeType, pName);
+    if (pMatchingNode == NULL && m_pChoice != NULL)
+        pMatchingNode = m_pSequence->getNodeByTypeAndNameDescending(eNodeType, pName);
+
+    return pMatchingNode;
+}
+
+void CComplexType::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+    QuickOutHeader(cout, XSD_COMPLEX_TYPE_STR, offset);
+
+    QUICK_OUT_2(Name)
+    QUICK_OUT(cout, XSDXPath,   offset);
+
+    if (m_pSequence != NULL)
+        m_pSequence->dump(cout, offset);
+    if (m_pComplexContent != NULL)
+        m_pComplexContent->dump(cout, offset);
+    if (m_pAttributeArray != NULL)
+        m_pAttributeArray->dump(cout, offset);
+    if (m_pChoice != NULL)
+        m_pChoice->dump(cout, offset);
+    if (m_pAttributeGroupArray != NULL)
+        m_pAttributeGroupArray->dump(cout, offset);
+    if (m_pAnnotation != NULL)
+        m_pAnnotation->dump(cout, offset);
+
+    QuickOutFooter(cout, XSD_COMPLEX_TYPE_STR, offset);
+}
+
+void CComplexType::getDocumentation(StringBuffer &strDoc) const
+{
+    if (m_pSequence != NULL)
+        m_pSequence->getDocumentation(strDoc);
+
+    if (m_pComplexContent != NULL)
+    {
+        strDoc.append(DM_SECT3_BEGIN);
+        DEBUG_MARK_STRDOC
+        m_pComplexContent->getDocumentation(strDoc);
+        strDoc.append(DM_SECT3_END);
+    }
+
+    if (m_pAttributeArray != NULL)
+    {
+        if (this->getConstParentNode()->getConstParentNode()->getNodeType() == XSD_SCHEMA)
+            strDoc.appendf("<%s>\n", DM_TABLE_ROW);
+
+        m_pAttributeArray->getDocumentation(strDoc);
+
+        if (this->getConstParentNode()->getConstParentNode()->getNodeType() == XSD_SCHEMA)
+            strDoc.appendf("</%s>\n", DM_TABLE_ROW);
+    }
+
+    if (m_pChoice != NULL)
+        m_pChoice->getDocumentation(strDoc);
+    if (m_pAttributeGroupArray != NULL)
+        m_pAttributeGroupArray->getDocumentation(strDoc);
+}
+
+void CComplexType::getJSON(StringBuffer &strJSON, unsigned int offset, int idx) const
+{
+	bool bAddComma = false;
+
+    if ((m_pAttributeArray != NULL && m_pAttributeArray->length() > 0) || m_pSequence != NULL || m_pAttributeGroupArray != NULL)
+	{
+        strJSON.append("\n");
+        offset += STANDARD_OFFSET_2;
+        QuickOutPad(strJSON, offset);
+        CONTENT_INNER_CONTENT_BEGIN
+
+        //bAddComma = true;
+	}
+
+    if (m_pAttributeArray != NULL && m_pAttributeArray->length() > 0)
+    {
+        QuickOutPad(strJSON, offset);
+        //if (bAddComma)
+        {
+           strJSON.append("{");
+        }
+
+        const CElement *pElement = dynamic_cast<const CElement*>(this->getParentNodeByType(XSD_ELEMENT));
+        assert(pElement != NULL);
+
+        if (pElement && (pElement->getMaxOccursInt() > 0 || strlen(pElement->getMinOccurs()) > 0))
+        {
+            CJSONMarkUpHelper::createUIContent(strJSON, offset, JSON_TYPE_TABLE, "Attributes", this->getEnvXPath());
+        }
+        else if (m_pAttributeArray != NULL && m_pAttributeArray->length() > 0)
+        {
+            CJSONMarkUpHelper::createUIContent(strJSON, offset, JSON_TYPE_TAB, "Attributes", this->getEnvXPath());
+        }
+
+        CONTENT_INNER_CONTENT_BEGIN
+
+        m_pAttributeArray->getJSON(strJSON, offset);
+        bAddComma = true;
+
+        INNER_CONTENT_END
+
+        strJSON.append("}");
+
+        if (bAddComma)
+        {
+            strJSON.append("}");
+        }
+
+        bAddComma = true;
+    }
+    if (m_pSequence != NULL)
+    {
+        if (bAddComma)
+        {
+            strJSON.append(",");
+        }
+
+        m_pSequence->getJSON(strJSON, offset);
+        bAddComma = true;
+    }
+
+    if (m_pChoice != NULL)
+    {
+        if (bAddComma)
+        {
+            strJSON.append(",");
+        }
+
+        m_pChoice->getJSON(strJSON, offset);
+        //bAddComma = true;
+    }
+
+    if(m_pAttributeGroupArray != NULL && m_pAttributeGroupArray->length() > 0)
+    {
+        if (bAddComma)
+        {
+            strJSON.append(",");
+        }
+        m_pAttributeGroupArray->getJSON(strJSON, offset);
+    }
+    INNER_CONTENT_END
+    CONTENT_CONTENT_END
+}
+
+void CComplexType::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    this->setEnvXPath(strXPath);
+
+    if (m_pSequence != NULL)
+        m_pSequence->populateEnvXPath(strXPath, index);
+    if (m_pComplexContent != NULL)
+        m_pComplexContent->populateEnvXPath(strXPath, index);
+    if (m_pAttributeArray != NULL)
+        m_pAttributeArray->populateEnvXPath(strXPath, index);
+    if (m_pChoice != NULL)
+        m_pChoice->populateEnvXPath(strXPath, index);
+    if (m_pAttributeGroupArray != NULL)
+        m_pAttributeGroupArray->populateEnvXPath(strXPath, index);
+}
+
+void CComplexType::loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+{
+    if (m_pSequence != NULL)
+        m_pSequence->loadXMLFromEnvXml(pEnvTree);
+    if (m_pComplexContent != NULL)
+        m_pComplexContent->loadXMLFromEnvXml(pEnvTree);
+    if (m_pAttributeArray != NULL)
+        m_pAttributeArray->loadXMLFromEnvXml(pEnvTree);
+    if (m_pChoice != NULL)
+        m_pChoice->loadXMLFromEnvXml(pEnvTree);
+    if (m_pAttributeGroupArray != NULL)
+        m_pAttributeGroupArray->loadXMLFromEnvXml(pEnvTree);
+}
+
+const char* CComplexType::getXML(const char* /*pComponent*/)
+{
+    if (m_strXML.length() == 0)
+    {
+        if (m_pComplexContent != NULL)
+            m_strXML.append(m_pComplexContent->getXML(NULL));
+        if (m_pAttributeArray != NULL)
+            m_strXML.append(m_pAttributeArray->getXML(NULL));
+        if (m_pChoice != NULL)
+            m_strXML.append(m_pChoice->getXML(NULL));
+    }
+    return m_strXML.str();
+}
+
+bool CComplexType::hasChildElements() const
+{
+    if (this->m_pSequence != NULL)
+        return m_pSequence->hasChildElements();
+
+    return false;
+}
+
+CComplexType* CComplexType::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+
+    CComplexContent *pComplexContent = NULL;
+    CAttributeArray *pAttributeArray =  NULL;
+    CChoice *pChoice = NULL;
+    CSequence *pSequence  = NULL;
+    CAttributeGroupArray *pAttributeGroupArray = NULL;
+    CAnnotation *pAnnotation = NULL;
+
+    if (pSchemaRoot == NULL)
+        return NULL;
+
+    IPropertyTree *pTree = pSchemaRoot->queryPropTree(xpath);
+    const char* pName = pTree->queryProp(XML_ATTR_NAME);
+    StringBuffer strXPathExt(xpath);
+
+    strXPathExt.clear().append(xpath).append("/").append(XSD_TAG_SEQUENCE);
+    pSequence = CSequence::load(NULL, pSchemaRoot, strXPathExt.str());
+
+    strXPathExt.clear().append(xpath).append("/").append(XSD_TAG_ANNOTATION);
+    pAnnotation = CAnnotation::load(NULL, pSchemaRoot, strXPathExt.str());
+
+    strXPathExt.clear().append(xpath).append("/").append(XSD_TAG_COMPLEX_CONTENT);
+    pComplexContent = CComplexContent::load(NULL, pSchemaRoot, strXPathExt.str());
+
+    strXPathExt.clear().append(xpath).append("/").append(XSD_TAG_ATTRIBUTE);
+    pAttributeArray = CAttributeArray::load(NULL, pSchemaRoot, strXPathExt.str());
+
+    strXPathExt.clear().append(xpath).append("/").append(XSD_TAG_CHOICE);
+    pChoice = CChoice::load(NULL, pSchemaRoot, strXPathExt.str());
+
+    strXPathExt.clear().append(xpath).append("/").append(XSD_TAG_ATTRIBUTE_GROUP);
+    pAttributeGroupArray = CAttributeGroupArray::load(NULL, pSchemaRoot, strXPathExt.str());
+
+    CComplexType *pComplexType = new CComplexType(pParentNode, pName, pSequence, pComplexContent, pAttributeArray, pChoice, pAttributeGroupArray, pAnnotation);
+    pComplexType->setXSDXPath(xpath);
+
+    assert(pComplexType != NULL);
+
+    if (pComplexType != NULL)
+    {
+        SETPARENTNODE(pSequence, pComplexType)
+        SETPARENTNODE(pComplexContent, pComplexType)
+        SETPARENTNODE(pAttributeArray, pComplexType)
+        SETPARENTNODE(pChoice, pComplexType)
+        SETPARENTNODE(pAttributeGroupArray, pComplexType)
+        SETPARENTNODE(pAnnotation, pComplexType);
+
+        if (pName != NULL)
+            CConfigSchemaHelper::getInstance()->getSchemaMapManager()->setComplexTypeWithName(pName, pComplexType);
+    }
+    return pComplexType;
+}
+
+void CComplexTypeArray::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_COMPLEX_TYPE_ARRAY_STR, offset);
+
+    QUICK_OUT(cout, XSDXPath,   offset);
+    QUICK_OUT_ARRAY(cout, offset);
+
+    QuickOutFooter(cout, XSD_COMPLEX_TYPE_ARRAY_STR, offset);
+}
+
+void CComplexTypeArray::getDocumentation(StringBuffer &strDoc) const
+{
+    QUICK_DOC_ARRAY(strDoc);
+}
+
+void CComplexTypeArray::getJSON(StringBuffer &strJSON, unsigned int offset, int idx) const
+{
+    for (int idx=0; idx < this->length(); idx++)
+    {
+        (this->item(idx)).getJSON(strJSON, offset);
+    }
+}
+
+const char* CComplexTypeArray::getXML(const char* /*pComponent*/)
+{
+    if (m_strXML.length() == 0)
+    {
+        int length = this->length();
+
+        for (int idx = 0; idx < length; idx++)
+        {
+            CComplexType &ComplexType = this->item(idx);
+
+            m_strXML.append(ComplexType.getXML(NULL));
+
+            if (idx+1 < length)
+                m_strXML.append("\n");
+        }
+    }
+    return m_strXML.str();
+}
+
+void CComplexTypeArray::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    this->setEnvXPath(strXPath);
+    QUICK_ENV_XPATH_WITH_INDEX(strXPath, 1); // can only have 1 complex type array
+}
+
+void CComplexTypeArray::loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+{
+    assert(pEnvTree != NULL);
+    if (pEnvTree->hasProp(this->getEnvXPath()) == false)
+        throw MakeExceptionFromMap(EX_STR_XPATH_DOES_NOT_EXIST_IN_TREE);
+    else
+        QUICK_LOAD_ENV_XML(pEnvTree);
+}
+
+CComplexTypeArray* CComplexTypeArray::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+
+    if (pSchemaRoot == NULL)
+        return NULL;
+
+    CComplexTypeArray *pComplexTypeArray = new CComplexTypeArray(pParentNode);
+
+    pComplexTypeArray->setXSDXPath(xpath);
+
+    Owned<IPropertyTreeIterator> complexTypeIter = pSchemaRoot->getElements(xpath);
+
+    int count = 1;
+
+    ForEach(*complexTypeIter)
+    {
+        StringBuffer strXPathExt(xpath);
+        strXPathExt.appendf("[%d]", count);
+
+        CComplexType *pComplexType = CComplexType::load(pComplexTypeArray, pSchemaRoot, strXPathExt.str());
+
+        assert(pComplexType != NULL);
+
+        if (pComplexType != NULL)
+            pComplexTypeArray->append(*pComplexType);
+
+        count++;
+    }
+
+    if (pComplexTypeArray->length() == 0)
+    {
+        delete pComplexTypeArray;
+        pComplexTypeArray = NULL;
+    }
+
+    return pComplexTypeArray;
+}
+
+CComplexTypeArray* CComplexTypeArray::load(CXSDNodeBase* pParentNode, const char* pSchemaFile)
+{
+    assert(false);  // why do still need to call this?
+    assert(pSchemaFile != NULL);
+
+    if (pSchemaFile == NULL)
+        return NULL;
+
+    if (pParentNode == NULL)
+    {
+        Linked<IPropertyTree> pSchemaRoot;
+
+        StringBuffer schemaPath;
+
+        schemaPath.appendf("%s%s", DEFAULT_SCHEMA_DIRECTORY, pSchemaFile);
+        pSchemaRoot.setown(createPTreeFromXMLFile(schemaPath.str()));
+
+        return CComplexTypeArray::load(pParentNode, pSchemaRoot, XSD_TAG_COMPLEX_TYPE);
+    }
+    else
+    {
+        CSchema *pSchema = (dynamic_cast<CSchema*>(pParentNode));
+
+        if (pSchema != NULL)
+            return pSchema->getComplexTypeArray();
+    }
+    return NULL;
+}

+ 131 - 0
configuration/configurator/SchemaComplexType.hpp

@@ -0,0 +1,131 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_COMPLEX_TYPE_HPP
+#define _SCHEMA_COMPLEX_TYPE_HPP
+
+#include "SchemaCommon.hpp"
+#include "jarray.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CSequence;
+class CComplexContent;
+class CAttributeArray;
+class CChoice;
+class CComplexType;
+class CAttributeGroupArray;
+class CAnnotation;
+
+class CComplexType : public CXSDNode
+{
+public:
+
+    virtual ~CComplexType()
+    {
+    }
+
+    GETTERSETTER(Name)
+
+    virtual const CXSDNodeBase* getNodeByTypeAndNameDescending(NODE_TYPES eNodeType, const char *pName) const;
+    virtual const CXSDNodeBase* getNodeByTypeAndNameAscending(NODE_TYPES eNodeType, const char *pName) const;
+
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const;
+    virtual void getJSON(::StringBuffer &strJSON, unsigned int offset = 0, int idx = -1) const;
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+    virtual const char* getXML(const char* /*pComponent*/);
+
+    virtual const CAttributeArray* getAttributeArray() const
+    {
+        return m_pAttributeArray;
+    }
+
+    virtual const CAttributeGroupArray* getAttributeGroupArray() const
+    {
+        return m_pAttributeGroupArray;
+    }
+
+    virtual const CSequence* getSequence() const
+    {
+        return m_pSequence;
+    }
+
+    virtual CAnnotation* getAnnotation() const
+    {
+        return m_pAnnotation;
+    }
+
+    bool hasChildElements() const;
+
+    static CComplexType* load(CXSDNodeBase* pRootNode, const ::IPropertyTree *pSchemaRoot, const char* xpath = NULL);
+
+protected:
+
+    CComplexType(CXSDNodeBase* pParentNode, const char* pName = NULL, CSequence *pSequence = NULL, CComplexContent *pComplexContent = NULL, CAttributeArray *pAttributeArray = NULL, \
+        CChoice *pChoice = NULL, CAttributeGroupArray *pAttributeGroupArray = NULL, CAnnotation *pAnnotation = NULL) : CXSDNode::CXSDNode(pParentNode, XSD_COMPLEX_TYPE), \
+        m_strName(pName), m_pSequence(pSequence), m_pComplexContent(pComplexContent), m_pAttributeArray(pAttributeArray), m_pChoice(pChoice), \
+        m_pAttributeGroupArray(pAttributeGroupArray), m_pAnnotation(pAnnotation)
+    {
+    }
+
+    CSequence*              m_pSequence;
+    CComplexContent*        m_pComplexContent;
+    CAttributeArray*        m_pAttributeArray;
+    CChoice*                m_pChoice;
+    CAttributeGroupArray*   m_pAttributeGroupArray;
+    CAnnotation*            m_pAnnotation;
+
+private:
+
+    CComplexType() : CXSDNode::CXSDNode(NULL)
+    {
+    }
+
+};
+
+class CComplexTypeArray : public ::CIArrayOf<CComplexType>, public InterfaceImpl, public CXSDNodeBase
+{
+public:
+
+    CComplexTypeArray(CXSDNodeBase* pParentNode = NULL) : CXSDNodeBase::CXSDNodeBase(pParentNode, XSD_COMPLEX_TYPE_ARRAY)
+    {
+    }
+
+    virtual ~CComplexTypeArray()
+    {
+    }
+
+//    virtual const CXSDNodeBase* getNodeByTypeAndNameDescending(NODE_TYPES eNodeType, const char *pName) const;
+//    virtual const CXSDNodeBase* getNodeByTypeAndNameAscending(NODE_TYPES eNodeType, const char *pName) const;
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const;
+    virtual void getJSON(::StringBuffer &strJSON, unsigned int offset = 0, int idx = -1) const;
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+    virtual const char* getXML(const char* /*pComponent*/);
+
+    static CComplexTypeArray* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath = NULL);
+    static CComplexTypeArray* load(CXSDNodeBase* pParentNode, const char* pSchemaFile);
+
+protected:
+private:
+};
+} // namespace CONFIGURATOR
+#endif // _SCHEMA_COMPLEX_TYPE_HPP

+ 56 - 0
configuration/configurator/SchemaDocumentation.cpp

@@ -0,0 +1,56 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jptree.hpp"
+#include "jstring.hpp"
+#include "SchemaDocumentation.hpp"
+#include "DocumentationMarkup.hpp"
+
+using namespace CONFIGURATOR;
+
+void CDocumentation::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_DOCUMENTATION_STR, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QUICK_OUT(cout,Documentation, offset);
+    QuickOutFooter(cout, XSD_DOCUMENTATION_STR, offset);
+}
+
+CDocumentation* CDocumentation::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    if (pSchemaRoot == NULL)
+        return NULL;
+    if (pSchemaRoot->queryPropTree(xpath) == NULL)
+        return NULL; // no documentation node
+
+    StringBuffer strDoc;
+
+    if (xpath && *xpath)
+        strDoc.append(pSchemaRoot->queryPropTree(xpath)->queryProp(""));
+
+    CDocumentation *pDocumentation = new CDocumentation(pParentNode, strDoc.str());
+    pDocumentation->setXSDXPath(xpath);
+
+    return pDocumentation;
+}
+
+void  CDocumentation::getDocumentation(StringBuffer &strDoc) const
+{
+    strDoc.appendf("%s%s%s", DM_PARA_BEGIN, this->getDocString(), DM_PARA_END);
+}

+ 62 - 0
configuration/configurator/SchemaDocumentation.hpp

@@ -0,0 +1,62 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_DOCUMENATION_HPP_
+#define _SCHEMA_DOCUMENATION_HPP_
+
+#include "jiface.hpp"
+#include "jstring.hpp"
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CDocumentation : public CXSDNode
+{
+public:
+
+    virtual ~CDocumentation()
+    {
+    }
+
+    GETTERSETTER(DocString)
+
+    const char* getDocumentation() const
+    {
+        return m_strDocString.str();
+    }
+
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(StringBuffer &strDoc) const;
+
+    static CDocumentation* load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath = NULL);
+
+protected:
+
+    CDocumentation(CXSDNodeBase* pParentNode, const char *pDocs = NULL) : CXSDNode::CXSDNode(pParentNode, XSD_DOCUMENTATION), m_strDocString(pDocs)
+    {
+    }
+
+private:
+
+    CDocumentation() : CXSDNode::CXSDNode(NULL, XSD_DOCUMENTATION)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_DOCUMENATION_HPP_

+ 887 - 0
configuration/configurator/SchemaElement.cpp

@@ -0,0 +1,887 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include <cassert>
+#include "jptree.hpp"
+#include "jstring.hpp"
+#include "jarray.hpp"
+#include "jhash.hpp"
+#include "XMLTags.h"
+
+
+//#define ::StringBuffer ::::StringBuffer
+//#define ::IPropertyTree ::::IPropertyTree
+
+#include "SchemaAnnotation.hpp"
+#include "SchemaCommon.hpp"
+#include "SchemaElement.hpp"
+#include "SchemaComplexType.hpp"
+#include "SchemaElement.hpp"
+#include "SchemaAttributes.hpp"
+#include "SchemaAppInfo.hpp"
+#include "SchemaDocumentation.hpp"
+#include "DocumentationMarkup.hpp"
+#include "ConfigSchemaHelper.hpp"
+#include "ConfigSchemaHelper.hpp"
+#include "SchemaMapManager.hpp"
+#include "ConfiguratorMain.hpp"
+#include "JSONMarkUp.hpp"
+
+using namespace CONFIGURATOR;
+
+const CXSDNodeBase* CElement::getNodeByTypeAndNameAscending(NODE_TYPES eNodeType, const char *pName) const
+{
+    const CXSDNodeBase* pMatchingNode = NULL;
+
+    if (eNodeType == this->getNodeType() && (pName != NULL ? !strcmp(pName, this->getNodeTypeStr()) : true))
+        return this;
+
+    if (eNodeType == XSD_ELEMENT)
+        pMatchingNode = (dynamic_cast<CElement*>(this->getParentNode()))->getNodeByTypeAndNameAscending(XSD_ELEMENT, pName);
+    if (pMatchingNode == NULL)
+        pMatchingNode = (dynamic_cast<CElementArray*>(this->getParentNode()))->getNodeByTypeAndNameAscending(eNodeType, pName);
+
+    return pMatchingNode;
+}
+
+const CXSDNodeBase* CElement::getNodeByTypeAndNameDescending(NODE_TYPES eNodeType, const char *pName) const
+{
+    const CXSDNodeBase* pMatchingNode = NULL;
+
+    if (eNodeType == this->getNodeType() && (pName != NULL ? !strcmp(pName, this->getNodeTypeStr()) : true))
+        return this;
+    if (m_pComplexTypeArray != NULL)
+        pMatchingNode = m_pComplexTypeArray->getNodeByTypeAndNameDescending(eNodeType, pName);
+
+    return pMatchingNode;
+}
+
+CElement* CElement::load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath, bool bIsInXSD)
+{
+    assert(pSchemaRoot != NULL);
+    assert(pParentNode != NULL);
+
+    if (pSchemaRoot == NULL || pParentNode == NULL)
+        return NULL;
+
+    CElement *pElement = new CElement(pParentNode);
+
+    pElement->setIsInXSD(bIsInXSD);
+    pElement->setXSDXPath(xpath);
+
+    ::IPropertyTree *pTree = pSchemaRoot->queryPropTree(xpath);
+
+    if (pElement != NULL && pTree != NULL)
+        pElement->setName(pTree->queryProp(XML_ATTR_NAME));
+
+    Owned<IAttributeIterator> iterAttrib = pTree->getAttributes(true);
+
+    ForEach(*iterAttrib)
+    {
+        if (strcmp(iterAttrib->queryName(), XML_ATTR_NAME) == 0)
+        {
+            const char *pName = iterAttrib->queryValue();
+
+            if (pName != NULL && *pName != 0)
+                pElement->setName(pName);
+        }
+        else if (strcmp(iterAttrib->queryName(), XML_ATTR_MAXOCCURS) == 0)
+            pElement->setMaxOccurs(iterAttrib->queryValue());
+        else if (strcmp(iterAttrib->queryName(), XML_ATTR_MINOCCURS) == 0)
+            pElement->setMinOccurs(iterAttrib->queryValue());
+        else if (strcmp(iterAttrib->queryName(), XML_ATTR_TYPE) == 0)
+        {
+            const char *pType = iterAttrib->queryValue();
+
+            assert(pType != NULL && *pType != 0);
+
+            if (pType != NULL && *pType != 0)
+            {
+                pElement->setType(pType);
+                CConfigSchemaHelper::getInstance()->addNodeForTypeProcessing(pElement);
+            }
+        }
+        else if (strcmp(iterAttrib->queryName(), XML_ATTR_REF) == 0)
+        {
+            const char *pRef = iterAttrib->queryValue();
+
+            assert (pRef != NULL && *pRef != 0 && pElement->getConstAncestorNode(3)->getNodeType() != XSD_SCHEMA);
+
+            if (pRef != NULL && *pRef != 0 && pElement->getConstAncestorNode(3)->getNodeType() != XSD_SCHEMA)
+            {
+                pElement->setRef(pRef);
+                CConfigSchemaHelper::getInstance()->addElementForRefProcessing(pElement);
+            }
+            else
+            {
+                // TODO:  throw exception
+            }
+        }
+        else if (strcmp(iterAttrib->queryName(), XML_ATTR_DEFAULT) == 0)
+        {
+            const char *pDefault = iterAttrib->queryValue();
+
+            assert(pDefault != NULL);
+            assert(strlen(pElement->getDefault()) == 0);
+            pElement->setDefault(pDefault);
+        }
+        assert(iterAttrib->queryValue() != NULL);
+    }
+    assert(strlen(pElement->getName()) > 0);
+
+    if (strlen(pElement->getRef()) != 0)
+    {
+        assert(pElement->getComplexTypeArray()->length() == 0);
+        assert(pElement->getSimpleType() == NULL);
+        assert(strlen(pElement->getDefault()) == 0);
+        assert(strlen(pElement->getType()) == 0);
+        /*assert(pElement->getKey() == NULL);
+        assert(pElement->getKeyRef() == NULL);
+        assert(pElement->getUnique() == NULL);*/
+    }
+
+    ::StringBuffer strXPathExt(xpath);
+
+    strXPathExt.append("/").append(XSD_TAG_ANNOTATION);
+    pElement->m_pAnnotation = CAnnotation::load(pElement, pSchemaRoot, strXPathExt.str());
+
+    strXPathExt.clear().append(xpath).append("/").append(XSD_TAG_COMPLEX_TYPE);
+    pElement->m_pComplexTypeArray = CComplexTypeArray::load(pElement, pSchemaRoot, strXPathExt.str());
+
+    if (pElement->m_pAnnotation != NULL && pElement->m_pAnnotation->getAppInfo() != NULL && strlen(pElement->m_pAnnotation->getAppInfo()->getTitle()) > 0)
+    {
+        /****  MUST FIX TO HAVE CORRECT UI TAB LABELS (but getName is expected to return the XPATH name *****/
+        //pElement->setName(pElement->m_pAnnotation->getAppInfo()->getTitle());
+        pElement->setTitle(pElement->m_pAnnotation->getAppInfo()->getTitle());
+    }
+    else
+        pElement->setTitle(pElement->getName());
+
+/*    strXPathExt.clear().append(xpath).append("/").append(XSD_TAG_KEY);
+    pElement->m_pKeyArray = CKeyArray::load(pElement, pSchemaRoot, strXPathExt.str());
+
+    strXPathExt.clear().append(xpath).append("/").append(XSD_TAG_KEYREF);
+    pElement->m_pKeyRefArray = CKeyRefArray::load(pElement, pSchemaRoot, strXPathExt.str());
+*/
+    strXPathExt.clear().append(xpath).append("/").append(XSD_TAG_SIMPLE_TYPE);
+    pElement->m_pSimpleType = CSimpleType::load(pElement, pSchemaRoot, strXPathExt.str());
+
+    SETPARENTNODE(pElement, pParentNode);
+
+    return pElement;
+}
+
+const CElement* CElement::getTopMostElement(const CXSDNodeBase *pNode)
+{
+    if (pNode == NULL)
+        return NULL;
+    else if (pNode->getNodeType() == XSD_ELEMENT)
+    {
+        if (pNode->getParentNodeByType(XSD_ELEMENT) == NULL)
+        {
+            assert(dynamic_cast<const CElement*>(pNode) != NULL);
+            return dynamic_cast<const CElement*>(pNode);
+        }
+    }
+    return getTopMostElement(pNode->getParentNodeByType(XSD_ELEMENT));
+}
+
+const CSchema* CElement::getConstSchemaNode() const
+{
+    const CSchema *pSchema = dynamic_cast<const CSchema*>(CElement::getTopMostElement(this)->getParentNodeByType(XSD_SCHEMA));
+    return pSchema;
+}
+
+const char* CElement::getXML(const char* /*pComponent*/)
+{
+    if (m_strXML.length () == 0)
+    {
+        m_strXML.append("\n<").append(getName()).append(" ");
+
+        if (m_pAnnotation != NULL)
+            m_strXML.append(m_pAnnotation->getXML(NULL));
+        if (m_pComplexTypeArray != NULL)
+            m_strXML.append(m_pComplexTypeArray->getXML(NULL));
+        if (m_pKeyArray != NULL)
+            m_strXML.append(m_pKeyArray->getXML(NULL));
+        if (m_pKeyRefArray != NULL)
+            m_strXML.append(m_pKeyRefArray->getXML(NULL));
+    }
+    return m_strXML.str();
+}
+
+void CElement::dump(::std::ostream &cout, unsigned int offset) const
+{
+    offset += STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_ELEMENT_STR, offset);
+    QUICK_OUT(cout, Name, offset);
+    QUICK_OUT(cout, Type, offset);
+    QUICK_OUT(cout, MinOccurs, offset);
+    QUICK_OUT(cout, MaxOccurs, offset);
+    QUICK_OUT(cout, Title,  offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QUICK_OUT(cout, EnvXPath,  offset);
+    QUICK_OUT(cout, EnvValueFromXML,  offset);
+    QUICK_OUT(cout, Ref, offset);
+
+    if (this->getTypeNode() != NULL)
+        this->getTypeNode()->dump(cout, offset);
+    if (m_pAnnotation != NULL)
+        m_pAnnotation->dump(cout, offset);
+    if (m_pComplexTypeArray != NULL)
+        m_pComplexTypeArray->dump(cout, offset);
+    if (m_pKeyArray != NULL)
+        m_pKeyArray->dump(cout, offset);
+    if (m_pKeyRefArray != NULL)
+        m_pKeyRefArray->dump(cout, offset);
+    if (m_pSimpleType != NULL)
+        m_pSimpleType->dump(cout, offset);
+
+    if (this->getRef() != NULL)
+    {
+        CElement *pElement = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getElementWithName(this->getRef());
+
+        assert(pElement != NULL);
+        if (pElement != NULL)
+            pElement->dump(cout, offset);
+    }
+    QuickOutFooter(cout, XSD_ELEMENT_STR, offset);
+}
+
+void CElement::getDocumentation(::StringBuffer &strDoc) const
+{
+    const CXSDNodeBase *pGrandParentNode = this->getConstParentNode()->getConstParentNode();
+
+    assert(pGrandParentNode != NULL);
+    if (pGrandParentNode == NULL)
+        return;
+
+    if (m_pAnnotation != NULL && m_pAnnotation->getAppInfo() != NULL && m_pAnnotation->getAppInfo()->getViewType() != NULL && stricmp(m_pAnnotation->getAppInfo()->getViewType(), "none") == 0)
+        return;
+
+    if (this->getName() != NULL && (stricmp(this->getName(), "Instance") == 0 || stricmp(this->getName(), "Note") == 0 || stricmp(this->getName(), "Notes") == 0 ||  stricmp(this->getName(), "Topology") == 0 ))
+        return; // don't document instance
+
+    assert(strlen(this->getName()) > 0);
+
+    if (pGrandParentNode->getNodeType() == XSD_SCHEMA)
+    {
+        ::StringBuffer strName(this->getName());
+
+        strName.replace(' ', '_');
+        strDoc.append(DM_HEADING);
+
+        // component name would be here
+        strDoc.appendf("<%s %s=\"%s%s\">\n", DM_SECT2, DM_ID, strName.str(),"_mod");
+        strDoc.appendf("<%s>%s</%s>\n", DM_TITLE_LITERAL, this->getName(), DM_TITLE_LITERAL);
+
+        if (m_pAnnotation!= NULL)
+        {
+            m_pAnnotation->getDocumentation(strDoc);
+            DEBUG_MARK_STRDOC;
+        }
+
+        strDoc.append(DM_SECT3_BEGIN);
+        DEBUG_MARK_STRDOC;
+        strDoc.append(DM_TITLE_BEGIN).append(DM_TITLE_END);
+
+        if (m_pComplexTypeArray != NULL)
+            m_pComplexTypeArray->getDocumentation(strDoc);
+
+        strDoc.append(DM_SECT3_END);
+        return;
+    }
+    else if (m_pComplexTypeArray != NULL)
+    {
+        if (m_pAnnotation!= NULL)
+        {
+            m_pAnnotation->getDocumentation(strDoc);
+            DEBUG_MARK_STRDOC;
+        }
+
+        if (pGrandParentNode->getNodeType() == XSD_CHOICE)
+            strDoc.appendf("%s%s%s", DM_PARA_BEGIN, this->getTitle(), DM_PARA_END);
+        else
+            strDoc.appendf("%s%s%s", DM_TITLE_BEGIN, this->getTitle(), DM_TITLE_END);
+
+        DEBUG_MARK_STRDOC;
+        m_pComplexTypeArray->getDocumentation(strDoc);
+    }
+    else if (m_pComplexTypeArray == NULL)
+    {
+        if (m_pAnnotation!= NULL)
+        {
+            m_pAnnotation->getDocumentation(strDoc);
+            DEBUG_MARK_STRDOC;
+        }
+
+        strDoc.appendf("%s%s%s", DM_PARA_BEGIN, this->getName(), DM_PARA_END);
+        DEBUG_MARK_STRDOC;
+
+        if (m_pAnnotation != NULL && m_pAnnotation->getDocumentation() != NULL)
+        {
+            m_pAnnotation->getDocumentation(strDoc);
+            DEBUG_MARK_STRDOC;
+        }
+    }
+}
+
+void CElement::getJSON(::StringBuffer &strJSON, unsigned int offset, int idx) const
+{
+    assert(this->getConstAncestorNode(3) != NULL);
+
+//    if (m_pAnnotation != NULL && m_pAnnotation->getAppInfo() != NULL && m_pAnnotation->getAppInfo()->getViewType() != NULL && stricmp(m_pAnnotation->getAppInfo()->getViewType(), "none") == 0)
+//        return;
+
+    assert(strlen(this->getName()) > 0);
+
+    StringBuffer strXPath(this->getEnvXPath());
+
+    stripTrailingIndex(strXPath);
+
+    if (m_pComplexTypeArray != NULL  && m_pComplexTypeArray->length() > 0)
+    {
+        //CJSONMarkUpHelper::createUIContent(strJSON, offset, (this->getMaxOccursInt() > 1 || strlen(this->getMinOccurs()) > 0) ? JSON_TYPE_TABLE : JSON_TYPE_TAB, this->getTitle(), this->getEnvXPath());
+
+        //CJSONMarkUpHelper::createUIContent(strJSON, offset, (this->getMaxOccursInt() > 1 || strlen(this->getMinOccurs()) > 0) ? JSON_TYPE_TABLE : JSON_TYPE_TAB, this->getTitle(), strXPath.str());
+        CJSONMarkUpHelper::createUIContent(strJSON, offset, JSON_TYPE_TAB, this->getTitle(), strXPath.str());
+
+        m_pComplexTypeArray->getJSON(strJSON, offset);
+    }
+    else
+    {
+        //CJSONMarkUpHelper::createUIContent(strJSON, offset, JSON_TYPE_TABLE, this->getTitle(), this->getEnvXPath());
+        CJSONMarkUpHelper::createUIContent(strJSON, offset, JSON_TYPE_TABLE, this->getTitle(), strXPath.str());
+        // add values
+        //CJSONMarkUpHelper::createUIContent(strJSON, offset, JSON_TYPE_INPUT, this->getTitle(),  strXPath.str());
+    }
+}
+
+
+bool CElement::isATab() const
+{
+    const CComplexTypeArray *pComplexTypArray = this->getComplexTypeArray();
+    const CAttributeGroupArray *pAttributeGroupArray = (pComplexTypArray != NULL && pComplexTypArray->length() > 0) ? pComplexTypArray->item(0).getAttributeGroupArray() : NULL;
+    const CAttributeArray *pAttributeArray = (pComplexTypArray != NULL && pComplexTypArray->length() > 0) ? pComplexTypArray->item(0).getAttributeArray() : NULL;
+
+    if (this->getConstAncestorNode(3)->getNodeType() != XSD_SCHEMA && \
+            (this->hasChildElements() == true || \
+             (this->hasChildElements() == false && (static_cast<const CElementArray*>(this->getConstParentNode()))->anyElementsHaveMaxOccursGreaterThanOne() == false)/* || \
+             (this->isTopLevelElement() == true && (pAttributeGroupArray != NULL || pAttributeArray != NULL))*/))
+
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+/*    if (stricmp(this->getMaxOccurs(), TAG_UNBOUNDED) == 0)
+    {
+        return false;
+    }
+    // Any element that is in sequence of complex type will be a tab
+    else*/ if (this->getConstAncestorNode(3)->getNodeType() == XSD_SEQUENCE && this->getConstAncestorNode(3)->getNodeType() == XSD_COMPLEX_TYPE)
+    {
+        return true;
+    }
+    else if (/*this->getConstAncestorNode(3)->getNodeType == XSD_COMPLEX_TYPE &&*/ this->getConstAncestorNode(3)->getNodeType() == XSD_ELEMENT)
+    {
+        const CElement *pElement = dynamic_cast<const CElement*>(this->getConstAncestorNode(3));
+
+        assert(pElement != NULL);
+        if (pElement != NULL)
+            return pElement->isATab();
+    }
+    return false;
+}
+
+bool CElement::isLastTab(const int idx) const
+{
+    assert(this->isATab() == true);
+
+    const CElementArray *pElementArray = dynamic_cast<const CElementArray*>(this->getConstParentNode());
+
+    if (pElementArray == NULL)
+    {
+        assert(!"Corrupt XSD??");
+        return false;
+    }
+    if (pElementArray->length()-1 == idx)
+        return true;
+
+    return false;
+}
+
+
+void CElement::populateEnvXPath(::StringBuffer strXPath, unsigned int index)
+{
+    assert(strXPath.length() > 0);
+
+    //strXPath.append("/").append(this->getName()).append("[").append(index).append("]");
+    strXPath.append("[").append(index).append("]");
+
+    //PROGLOG("Setting element to envpath of %s, previous path: %s", strXPath.str(), this->getEnvXPath());
+    this->setEnvXPath(strXPath);
+
+    CConfigSchemaHelper::getInstance()->getSchemaMapManager()->addMapOfXPathToElement(this->getEnvXPath(), this);
+
+    if (m_pComplexTypeArray != NULL)
+        m_pComplexTypeArray->populateEnvXPath(strXPath, index);
+    if (m_pSimpleType != NULL)
+        m_pSimpleType->populateEnvXPath(strXPath, index);
+    if (m_pKeyArray != NULL)
+        m_pKeyArray->populateEnvXPath(strXPath, index);
+}
+
+void CElement::loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree)
+{
+    //PROGLOG("Mapping element with XPATH of %s to %p", this->getEnvXPath(), this);
+    //CConfigSchemaHelper::getInstance()->getSchemaMapManager()->addMapOfXPathToElement(this->getEnvXPath(), this);
+
+    if (m_pComplexTypeArray != NULL)
+    {
+        try
+        {
+            m_pComplexTypeArray->loadXMLFromEnvXml(pEnvTree);
+        }
+        catch (...)
+        {
+            // node described in XSD doesn't exist in XML
+            // time to do validation?
+        }
+    }
+    if (m_pSimpleType != NULL)
+    {
+        try
+        {
+            m_pSimpleType->loadXMLFromEnvXml(pEnvTree);
+        }
+        catch(...)
+        {
+        }
+    }
+
+    if (m_pComplexTypeArray == NULL)
+    {
+        const char* pValue =  pEnvTree->queryPropTree(this->getEnvXPath())->queryProp("");
+
+        if (pValue != NULL)
+        {
+            this->setEnvValueFromXML(pValue);
+            CConfigSchemaHelper::getInstance()->appendElementXPath(this->getEnvXPath());
+        }
+    }
+
+    const char* pInstanceName =  pEnvTree->queryPropTree(this->getEnvXPath())->queryProp(XML_ATTR_NAME);
+
+    if (pInstanceName != NULL && *pInstanceName != 0)
+        this->setInstanceName(pInstanceName);
+}
+
+bool CElement::isTopLevelElement() const
+{
+    return m_bTopLevelElement;
+}
+
+const char * CElement::getViewType() const
+{
+    if(m_pAnnotation != NULL && m_pAnnotation->getAppInfo() != NULL)
+        return m_pAnnotation->getAppInfo()->getViewType();
+    return NULL;
+}
+
+void CElementArray::dump(::std::ostream &cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_ELEMENT_ARRAY_STR, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QUICK_OUT(cout, EnvXPath,  offset);
+    QUICK_OUT_ARRAY(cout, offset);
+    QuickOutFooter(cout, XSD_ELEMENT_ARRAY_STR, offset);
+}
+
+void CElementArray::getDocumentation(::StringBuffer &strDoc) const
+{
+    QUICK_DOC_ARRAY(strDoc);
+}
+
+void CElementArray::getJSON(::StringBuffer &strJSON, unsigned int offset, int idx) const
+{
+    offset += STANDARD_OFFSET_2;
+    QuickOutPad(strJSON, offset);
+
+    int lidx = (idx == -1 ? 0 : idx);
+
+    strJSON.append("{");
+
+    (this->item(lidx)).getJSON(strJSON, offset+STANDARD_OFFSET_2, lidx);
+
+    offset += STANDARD_OFFSET_2;
+    QuickOutPad(strJSON, offset);
+    strJSON.append("}");
+}
+
+void CElementArray::populateEnvXPath(::StringBuffer strXPath, unsigned int index)
+{
+    strXPath.appendf("/%s", this->item(0).getName());
+    this->setEnvXPath(strXPath);
+
+    for (int idx=0; idx < this->length(); idx++)
+    {
+        //strXPath.appendf("[%d]", idx+1);
+        this->item(idx).populateEnvXPath(strXPath.str(), idx+1);
+        CConfigSchemaHelper::stripXPathIndex(strXPath);
+    }
+}
+
+const char* CElementArray::getXML(const char* /*pComponent*/)
+{
+    if (m_strXML.length() == 0)
+    {
+        int length = this->length();
+
+        for (int idx = 0; idx < length; idx++)
+        {
+            CElement &Element = this->item(idx);
+            m_strXML.append(Element.getXML(NULL));
+
+            if (idx+1 < length)
+                m_strXML.append("\n");
+        }
+    }
+    return m_strXML.str();
+}
+
+void CElementArray::loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree)
+{
+    ::StringBuffer strEnvXPath(this->getEnvXPath());
+    int subIndex = 1;
+
+    do
+    {
+        CElement *pElement = NULL;
+
+        strEnvXPath.appendf("[%d]", subIndex);
+        if (pEnvTree->hasProp(strEnvXPath.str()) == false)
+             return;
+
+        if (subIndex == 1)
+        {
+            pElement =  CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getElementFromXPath(strEnvXPath.str());
+        }
+        else
+        {
+            pElement = CElement::load(this, this->getSchemaRoot(), this->getXSDXPath(), false);
+            this->append(*pElement);
+        }
+
+        assert(pElement);
+
+        if (subIndex > 1)
+        {
+            pElement->populateEnvXPath(this->getEnvXPath(), subIndex);
+        }
+
+        pElement->setTopLevelElement(false);
+        pElement->loadXMLFromEnvXml(pEnvTree);
+
+        CConfigSchemaHelper::stripXPathIndex(strEnvXPath);
+
+        subIndex++;
+    } while (true);
+}
+
+CElementArray* CElementArray::load(const char* pSchemaFile)
+{
+    assert(pSchemaFile != NULL);
+    if (pSchemaFile == NULL)
+        return NULL;
+
+    typedef ::IPropertyTree jlibIPropertyTree;
+    ::Linked<jlibIPropertyTree> pSchemaRoot;
+    ::StringBuffer schemaPath;
+
+    schemaPath.appendf("%s%s", DEFAULT_SCHEMA_DIRECTORY, pSchemaFile);
+    pSchemaRoot.setown(createPTreeFromXMLFile(schemaPath.str()));
+
+    CElementArray *pElemArray = CElementArray::load(NULL, pSchemaRoot, XSD_TAG_ELEMENT);
+
+    //PROGLOG("Function: %s() at %s:%d", __func__, __FILE__, __LINE__);
+    //PROGLOG("pElemArray = %p", pElemArray);
+
+    return pElemArray;
+}
+
+CElementArray* CElementArray::load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    if (pSchemaRoot == NULL)
+        return NULL;
+
+    CElementArray *pElemArray = new CElementArray(pParentNode);
+    assert(pElemArray != NULL);
+
+    pSchemaRoot->Link();
+    pElemArray->setSchemaRoot(pSchemaRoot);
+
+    ::StringBuffer strXPathExt(xpath);
+    pElemArray->setXSDXPath(xpath);
+
+    CElement *pElem = CElement::load(pElemArray, pSchemaRoot, strXPathExt.str());
+
+    assert(pElem);
+    pElemArray->append(*pElem);
+
+    SETPARENTNODE(pElemArray, pParentNode);
+
+    return pElemArray;
+
+
+/*    typedef ::IPropertyTreeIterator jlibIPropertyTreeIterator;
+    Owned<jlibIPropertyTreeIterator> elemIter = pSchemaRoot->getElements(xpath);
+
+    CElement *pElem = CElement::load(pElemArray, pSchemaRoot, strXPathExt.str());
+
+    assert(pElem);
+    pElemArray->append(*pElem);
+
+    SETPARENTNODE(pElemArray, pParentNode);
+
+    return pElemArray;
+
+    int count = 1;
+
+    ForEach(*elemIter)
+    {
+        strXPathExt.set(xpath);
+        strXPathExt.appendf("[%d]", count);
+
+        CElement *pElem = CElement::load(pElemArray, pSchemaRoot, strXPathExt.str());
+
+        assert(pElem);
+        pElemArray->append(*pElem);
+
+        count++;
+    }
+
+    if (pElemArray->length() == 0)
+    {
+        delete pElemArray;
+        return NULL;
+    }
+
+    SETPARENTNODE(pElemArray, pParentNode);
+
+    return pElemArray;*/
+}
+
+int CElementArray::getCountOfSiblingElements(const char *pXPath) const
+{
+    assert(pXPath != NULL && *pXPath != 0);
+
+    int count = 0;
+
+    for (int idx=0; idx < this->length(); idx++)
+    {
+        if (strcmp(this->item(idx).getXSDXPath(), pXPath) == 0)
+            count++;
+    }
+    return count;
+}
+
+const CXSDNodeBase* CElementArray::getNodeByTypeAndNameAscending(NODE_TYPES eNodeType, const char *pName) const
+{
+    assert(pName != NULL);
+
+    for (int idx = 1; idx < this->length() && eNodeType == XSD_ELEMENT; idx++)
+    {
+        if (strcmp ((static_cast<CElement>(this->item(idx))).getName(), pName) == 0)
+            return &(this->item(idx));
+    }
+    return (this->getParentNode()->getNodeByTypeAndNameAscending(eNodeType, pName));
+}
+
+const CXSDNodeBase* CElementArray::getNodeByTypeAndNameDescending(NODE_TYPES eNodeType, const char *pName) const
+{
+    assert(pName != NULL);
+
+    if (eNodeType == this->getNodeType())
+        return this;
+
+    return (this->getParentNode()->getNodeByTypeAndNameDescending(eNodeType, pName));
+}
+
+const CElement* CElementArray::getElementByNameAscending(const char *pName) const
+{
+    for (int idx = 1; idx < this->length() ;idx++)
+    {
+        if (strcmp ((static_cast<CElement>(this->item(idx))).getName(), pName) == 0)
+            return &(this->item(idx));
+    }
+
+    assert(!("Control should not reach here, unknown pName?"));
+    return NULL;
+}
+
+const CElement* CElementArray::getElementByNameDescending(const char *pName) const
+{
+    for (int idx = 1; idx < this->length(); idx++)
+    {
+        if (strcmp ((static_cast<CElement>(this->item(idx))).getName(), pName) == 0)
+            return &(this->item(idx));
+    }
+    return NULL;
+}
+
+int CElementArray::getSiblingIndex(const char* pXSDXPath, const CElement* pElement)
+{
+    assert(pXSDXPath != NULL && *pXSDXPath != 0 && pElement != NULL);
+
+    int nSiblingIndex = 0;
+
+    for (int idx=0; idx < this->length(); idx++)
+    {
+        if (strcmp(this->item(idx).getXSDXPath(), pXSDXPath) == 0)
+        {
+            if (&(this->item(idx)) == pElement)
+                break;
+
+            nSiblingIndex++;
+        }
+    }
+    return nSiblingIndex;
+}
+
+bool CElementArray::anyElementsHaveMaxOccursGreaterThanOne() const
+{
+    int len = this->length();
+
+    for (int i = 0; i < len; i++)
+    {
+        if ((this->item(i)).getMaxOccursInt() > 1 || this->item(i).getMaxOccursInt() == -1)
+            return true;
+    }
+    return false;
+}
+void CElement::setIsInXSD(bool b)
+{
+    m_bIsInXSD = b;
+
+    if (m_bIsInXSD == true)
+    {
+        CElementArray *pElemArray = dynamic_cast<CElementArray*>(this->getParentNode());
+        assert(pElemArray != NULL);
+
+        if (pElemArray != NULL)
+            pElemArray->incCountOfElementsInXSD();
+    }
+}
+
+bool CElement::hasChildElements() const
+{
+    const CComplexTypeArray* pComplexTypeArray = this->getComplexTypeArray();
+
+    if (pComplexTypeArray != NULL && pComplexTypeArray->length() != 0)
+    {
+        int nLen = pComplexTypeArray->length();
+
+        for (int i = 0; i < nLen; i++)
+        {
+            if (pComplexTypeArray->item(i).hasChildElements() == true)
+                return true;
+        }
+    }
+    return false;
+}
+
+
+CArrayOfElementArrays* CArrayOfElementArrays::load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    if (pSchemaRoot == NULL)
+        return NULL;
+
+    CArrayOfElementArrays *pArrayOfElementArrays = new CArrayOfElementArrays(pParentNode);
+
+    /*pSchemaRoot->Link();
+    pArrayOfElementArrays->setSchemaRoot(pSchemaRoot);*/
+
+    ::StringBuffer strXPathExt(xpath);
+    pArrayOfElementArrays->setXSDXPath(xpath);
+
+    typedef ::IPropertyTreeIterator jlibIPropertyTreeIterator;
+    Owned<jlibIPropertyTreeIterator> elemIter = pSchemaRoot->getElements(xpath);
+
+    int count = 1;
+
+    ForEach(*elemIter)
+    {
+        strXPathExt.set(xpath);
+        strXPathExt.appendf("[%d]", count);
+
+        CElementArray *pElemArray = CElementArray::load(pArrayOfElementArrays, pSchemaRoot, strXPathExt.str());
+
+        assert(pElemArray);
+        pArrayOfElementArrays->append(*pElemArray);
+
+        count++;
+    }
+
+    return pArrayOfElementArrays;
+}
+
+void CArrayOfElementArrays::getDocumentation(::StringBuffer &strDoc) const
+{
+    for (int i = 0; i < this->length(); i++)
+    {
+        this->item(i).getDocumentation(strDoc);
+    }
+}
+
+void CArrayOfElementArrays::populateEnvXPath(::StringBuffer strXPath, unsigned int index)
+{
+    ::StringBuffer strCopy(strXPath);
+    CConfigSchemaHelper::stripXPathIndex(strCopy);
+    this->setEnvXPath(strCopy);
+
+    for (int i = 0; i < this->length(); i++)
+    {
+        this->item(i).populateEnvXPath(strXPath.str());
+        CConfigSchemaHelper::getInstance()->getSchemaMapManager()->addMapOfXSDXPathToElementArray(this->item(i).getXSDXPath(), &(this->item(i)));
+    }
+}
+
+void CArrayOfElementArrays::loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree)
+{
+    for (int i = 0; i < this->ordinality(); i++)
+    {
+        this->item(i).loadXMLFromEnvXml(pEnvTree);
+    }
+}
+
+void CArrayOfElementArrays::getJSON(::StringBuffer &strJSON, unsigned int offset, int idx) const
+{
+    for (int i = 0; i < this->ordinality(); i++)
+    {
+        if (i != 0)
+            strJSON.append(",\n");
+        this->item(i).getJSON(strJSON, offset);
+    }
+}

+ 266 - 0
configuration/configurator/SchemaElement.hpp

@@ -0,0 +1,266 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_ELEMENT_HPP_
+#define _SCHEMA_ELEMENT_HPP_
+
+#include "jiface.hpp"
+#include "jstring.hpp"
+#include "jlib.hpp"
+#include "jarray.hpp"
+#include "SchemaCommon.hpp"
+#include "SchemaComplexType.hpp"
+#include <climits>
+
+namespace CONFIGURATOR
+{
+
+class CAnnotation;
+class CComplexTypeArray;
+class CKeyArray;
+class CKeyRefArray;
+class CKeyRef;
+class CSchema;
+class CElementArray;
+class CSimpleType;
+
+static const char* DEFAULT_ELEMENT_ARRAY_XPATH(".");
+
+class CElement : public CXSDNodeWithType
+{
+public:
+
+    virtual ~CElement()
+    {
+    }
+
+    virtual const CXSDNodeBase* getNodeByTypeAndNameAscending(NODE_TYPES eNodeType, const char *pName) const;
+    virtual const CXSDNodeBase* getNodeByTypeAndNameDescending(NODE_TYPES eNodeType, const char *pName) const;
+    virtual const char* getXML(const char* /*pComponent*/);
+    virtual void dump(::std::ostream &cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strJS) const;
+    virtual void getJSON(::StringBuffer &strJSON, unsigned int offset = 0, int idx = -1) const;
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+    virtual bool isTopLevelElement() const;
+    const CSchema* getConstSchemaNode() const;
+
+    void setTopLevelElement(bool b = true)
+    {
+        m_bTopLevelElement =  b;
+    }
+    void setParentIndex(int index)
+    {
+        m_nParentIndex = index;
+    }
+    int getParentIndex() const
+    {
+        return m_nParentIndex;
+    }
+    const CAnnotation* getAnnotation() const
+    {
+        return m_pAnnotation;
+    }
+    const CSimpleType* getSimpleType() const
+    {
+        return m_pSimpleType;
+    }
+    const CComplexTypeArray* getComplexTypeArray() const
+    {
+        return m_pComplexTypeArray;
+    }
+
+    static const CXSDNodeBase* getAncestorElement(const CXSDNodeBase *pNode)
+    {
+         return pNode->getParentNodeByType(XSD_ELEMENT);
+    }
+    static const CElement* getTopMostElement(const CXSDNodeBase *pNode);
+    static bool isAncestorTopElement(const CXSDNodeBase *pNode)
+    {
+        return (pNode != NULL && pNode->getParentNodeByType(XSD_ELEMENT) == getTopMostElement(pNode));
+    }
+    void setRefElementNode(CElement *pElement)
+    {
+        assert (pElement != NULL && this->getRefElementNode() != NULL);
+        if (pElement != NULL)
+            this->m_pElementRefNode = pElement;
+    }
+    CElement* getRefElementNode() const
+    {
+        return this->m_pElementRefNode;
+    }
+
+    bool isATab() const;
+    bool isLastTab(const int idx) const;
+    bool getIsInXSD() const
+    {
+        return m_bIsInXSD;
+    }
+
+    bool hasChildElements() const;
+
+    int getMaxOccursInt() const
+    {
+        if (m_strMaxOccurs.length() == 0)  // not set
+            return SHRT_MIN;
+        else if (strcmp(m_strMaxOccurs.str(), TAG_UNBOUNDED) == 0)
+            return SHRT_MAX;
+        else
+            return atoi(m_strMaxOccurs.str());
+    }
+
+    int getMinOccursInt() const
+    {
+        if (m_strMinOccurs.length() == 0)
+            return -1;
+        else
+            return atoi(m_strMinOccurs.str());
+    }
+
+    static CElement* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath, bool bIsInXSD = true);
+
+    const char * getViewType() const;
+
+    GETTERSETTER(Name)
+    GETTERSETTER(MaxOccurs)
+    GETTERSETTER(MinOccurs)
+    GETTERSETTER(Title)
+    GETTERSETTER(InstanceName)
+    GETTERSETTER(Ref)
+    GETTERSETTER(Default)
+
+protected:
+
+    CElement(CXSDNodeBase* pParentNode, const char* pName = "") : CXSDNodeWithType::CXSDNodeWithType(pParentNode, XSD_ELEMENT), m_strMinOccurs(""), m_strMaxOccurs(""), m_strName(pName), m_pAnnotation(NULL),
+        m_pComplexTypeArray(NULL), m_pKeyArray(NULL), m_pKeyRefArray(NULL), m_pReverseKeyRefArray(NULL), m_pElementRefNode(NULL), m_pSimpleType(NULL),\
+        m_bTopLevelElement(false), m_nParentIndex(-1), m_bIsInXSD(true), m_strDefault("")
+    {
+    }
+
+    void setIsInXSD(bool b);
+
+    CAnnotation * m_pAnnotation;
+    CComplexTypeArray* m_pComplexTypeArray;
+    CKeyArray *m_pKeyArray;
+    CKeyRefArray *m_pKeyRefArray;
+    CKeyRefArray *m_pReverseKeyRefArray;
+    CElement *m_pElementRefNode;
+    CSimpleType *m_pSimpleType;
+
+    bool m_bTopLevelElement;
+    int m_nParentIndex;
+    bool m_bIsInXSD;
+
+private:
+};
+
+class CElementArray : public ::CIArrayOf<CElement>, /*public InterfaceImpl,*/ public CXSDNodeBase, public CInterface
+{
+    friend class CElement;
+public:
+    CElementArray(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot = NULL) : CXSDNodeBase::CXSDNodeBase(pParentNode, XSD_ELEMENT_ARRAY),\
+        m_pSchemaRoot(pSchemaRoot), m_nCountOfElementsInXSD(0)
+    {
+    }
+
+    virtual ~CElementArray()
+    {
+    }
+
+    virtual const CXSDNodeBase* getNodeByTypeAndNameAscending(NODE_TYPES eNodeType, const char *pName) const;
+    virtual const CXSDNodeBase* getNodeByTypeAndNameDescending(NODE_TYPES eNodeType, const char *pName) const;
+
+    const CElement* getElementByNameAscending(const char *pName) const;
+    const CElement* getElementByNameDescending(const char *pName) const;
+    virtual void dump(::std::ostream &cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const;
+    virtual void getJSON(::StringBuffer &strJSON, unsigned int offset = 0, int idx = -1) const;
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+    virtual const char* getXML(const char* /*pComponent*/);
+    virtual int getCountOfSiblingElements(const char *pXPath) const;
+    bool anyElementsHaveMaxOccursGreaterThanOne() const;
+
+    virtual void setSchemaRoot(const ::IPropertyTree *pSchemaRoot)
+    {
+        assert(m_pSchemaRoot == NULL);
+        assert(pSchemaRoot);
+
+        m_pSchemaRoot = pSchemaRoot;
+    }
+    const ::IPropertyTree* getSchemaRoot() const
+    {
+        return m_pSchemaRoot;
+    }
+    int getCountOfElementsInXSD() const
+    {
+        return m_nCountOfElementsInXSD;
+    }
+    void incCountOfElementsInXSD()
+    {
+        m_nCountOfElementsInXSD++;
+    }
+
+    static CElementArray* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath = DEFAULT_ELEMENT_ARRAY_XPATH);
+    static CElementArray* load(const char *pSchemaFile);
+
+protected:
+
+    const ::IPropertyTree *m_pSchemaRoot;
+    int m_nCountOfElementsInXSD;
+    int getSiblingIndex(const char* pXSDXPath, const CElement* pElement);
+
+private:
+
+    CElementArray() : CXSDNodeBase::CXSDNodeBase(NULL, XSD_ELEMENT_ARRAY)
+    {
+    }
+};
+
+class CArrayOfElementArrays : public ::CIArrayOf<CElementArray>, public InterfaceImpl, public CXSDNodeBase
+{
+    friend class CElementArray;
+
+public:
+    CArrayOfElementArrays(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot = NULL) : CXSDNodeBase::CXSDNodeBase(pParentNode, XSD_ARRAY_OF_ELEMENT_ARRAYS)
+    {
+    }
+
+    virtual ~CArrayOfElementArrays()
+    {
+        this->clear();
+    }
+
+    virtual void dump(::std::ostream &cout, unsigned int offset = 0) const
+    {
+        for(int idx = 0; idx < this->length(); idx++)
+        {
+            this->item(idx).dump(cout);
+        }
+    }
+
+    virtual void getJSON(::StringBuffer &strJSON, unsigned int offset = 0, int idx = -1) const;
+
+    virtual void getDocumentation(::StringBuffer &strDoc) const;
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+
+    static CArrayOfElementArrays* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath = DEFAULT_ELEMENT_ARRAY_XPATH);
+};
+
+}
+#endif // _SCHEMA_ELEMENT_HPP_

+ 198 - 0
configuration/configurator/SchemaEnumeration.cpp

@@ -0,0 +1,198 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaCommon.hpp"
+#include "SchemaAttributes.hpp"
+#include "SchemaEnumeration.hpp"
+#include "SchemaRestriction.hpp"
+#include "XMLTags.h"
+#include "jptree.hpp"
+#include "DocumentationMarkup.hpp"
+
+using namespace CONFIGURATOR;
+
+#define StringBuffer ::StringBuffer
+#define IPropertyTree ::IPropertyTree
+
+CEnumeration* CEnumeration::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    if (pSchemaRoot == NULL)
+        return NULL;
+
+    CEnumeration *pEnumeration = new CEnumeration(pParentNode);
+    pEnumeration->setXSDXPath(xpath);
+
+    if (xpath && *xpath)
+    {
+        IPropertyTree* pTree = pSchemaRoot->queryPropTree(xpath);
+
+        if (pTree == NULL)
+            return pEnumeration;
+
+        const char* pValue = pTree->queryProp(XML_ATTR_VALUE);
+
+        if (pValue != NULL)
+            pEnumeration->setValue(pValue);
+    }
+    return pEnumeration;
+}
+
+void CEnumeration::dump(::std::ostream &cout, unsigned int offset) const
+{
+    offset += STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_ENUMERATION_STR, offset);
+    QUICK_OUT(cout, Value, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QUICK_OUT(cout, EnvXPath,  offset);
+    QUICK_OUT(cout, EnvValueFromXML,  offset);
+    QuickOutFooter(cout, XSD_ENUMERATION_STR, offset);
+}
+
+void CEnumeration::getDocumentation(StringBuffer &strDoc) const
+{
+    strDoc.appendf("* %s %s\n", this->getValue(), DM_LINE_BREAK);
+}
+
+const char* CEnumeration::getXML(const char* /*pComponent*/)
+{
+    UNIMPLEMENTED;
+    return NULL;
+}
+
+void CEnumeration::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    assert(this->getValue() != NULL);
+    const CAttribute *pAttribute = dynamic_cast<const CAttribute*>(this->getParentNodeByType(XSD_ATTRIBUTE));
+
+    assert(pAttribute != NULL);
+    this->setEnvXPath(strXPath.str());
+}
+
+void CEnumeration::loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+{
+    assert(this->getEnvXPath() != NULL);
+    const CAttribute *pAttribute = dynamic_cast<const CAttribute*>(this->getParentNodeByType(XSD_ATTRIBUTE) );
+    assert(pAttribute != NULL);
+
+    StringBuffer strXPath(this->getEnvXPath());
+    strXPath.append("[@").append(pAttribute->getName()).append("=\"").append(this->getValue()).append("\"]");
+
+    if (pEnvTree->hasProp(strXPath.str()) == true)
+        this->setInstanceValueValid(true);
+    else
+        this->setInstanceValueValid(false);
+}
+
+void CEnumerationArray::dump(::std::ostream &cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_ENUMERATION_ARRAY_STR, offset);
+    QUICK_OUT_ARRAY(cout, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QUICK_OUT(cout, EnvXPath,  offset);
+    QuickOutFooter(cout, XSD_ENUMERATION_ARRAY_STR, offset);
+}
+
+void CEnumerationArray::getDocumentation(StringBuffer &strDoc) const
+{
+    strDoc.append("\nChoices are: \n").append(DM_LINE_BREAK);
+    QUICK_DOC_ARRAY(strDoc);
+}
+
+const char* CEnumerationArray::getXML(const char* /*pComponent*/)
+{
+    UNIMPLEMENTED;
+    return NULL;
+}
+
+void CEnumerationArray::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    assert(index == 1);  // Only 1 array of elements per node
+    QUICK_ENV_XPATH(strXPath)
+    this->setEnvXPath(strXPath);
+}
+
+void CEnumerationArray::loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+{
+    assert(pEnvTree != NULL);
+    if (pEnvTree->hasProp(this->getEnvXPath()) == false)
+        throw MakeExceptionFromMap(EX_STR_XPATH_DOES_NOT_EXIST_IN_TREE);
+    else
+        QUICK_LOAD_ENV_XML(pEnvTree)
+}
+
+int CEnumerationArray::getEnvValueNodeIndex() const
+{
+    int len = this->length();
+
+    for (int idx = 0; idx < len; idx++)
+    {
+        if (this->item(idx).isInstanceValueValid() == true)
+            return idx;
+    }
+    return 1;
+}
+
+void CEnumerationArray::setEnvValueNodeIndex(int index)
+{
+    assert(index >= 0);
+    assert(index < this->length());
+
+    for (int idx = 0; idx < this->length(); idx++)
+    {
+        if (this->item(idx).isInstanceValueValid() == true)
+            this->item(idx).setInstanceValueValid(false);
+    }
+    this->item(index).setInstanceValueValid(true);
+}
+
+CEnumerationArray* CEnumerationArray::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    if (pSchemaRoot == NULL)
+        return NULL;
+
+    CEnumerationArray *pEnumerationArray = new CEnumerationArray(pParentNode);
+    pEnumerationArray->setXSDXPath(xpath);
+
+    Owned<IPropertyTreeIterator> elemIter = pSchemaRoot->getElements(xpath);
+
+    int count = 1;
+
+    ForEach(*elemIter)
+    {
+        StringBuffer strXPathExt(xpath);
+        strXPathExt.appendf("[%d]", count);
+
+        CEnumeration *pEnumeration = CEnumeration::load(pEnumerationArray, pSchemaRoot, strXPathExt.str());
+        pEnumerationArray->append(*pEnumeration);
+
+        count++;
+    }
+
+    if (pEnumerationArray->length() == 0)
+    {
+        delete pEnumerationArray;
+        return NULL;
+    }
+
+    SETPARENTNODE(pEnumerationArray, pParentNode);
+    return pEnumerationArray;
+}

+ 98 - 0
configuration/configurator/SchemaEnumeration.hpp

@@ -0,0 +1,98 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_ENUMERATION_HPP_
+#define _SCHEMA_ENUMERATION_HPP_
+
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CEnumeration : public CXSDNode
+{
+public:
+    friend class CEnumerationArray;
+
+    virtual ~CEnumeration()
+    {
+    }
+
+    GETTERSETTER(Value)
+
+    virtual void dump(::std::ostream &cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const;
+    virtual const char* getXML(const char* /*pComponent*/);
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+    bool isInstanceValueValid() const
+    {
+        return m_bInstanceValueValid;
+    }
+    static CEnumeration* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+protected:
+
+    CEnumeration(CXSDNodeBase* pParentNode) : CXSDNode::CXSDNode(pParentNode, XSD_ENUMERATION), m_strValue(""), m_bInstanceValueValid(false)
+    {
+    }
+    void setInstanceValueValid(bool b)
+    {
+        m_bInstanceValueValid = b;
+    }
+
+    bool m_bInstanceValueValid;
+
+private:
+
+    CEnumeration() : CXSDNode::CXSDNode(NULL, XSD_ENUMERATION)
+    {
+    }
+};
+
+class CEnumerationArray : public CIArrayOf<CEnumeration>, public InterfaceImpl, public CXSDNodeBase
+{
+public:
+
+    CEnumerationArray(CXSDNodeBase* pParentNode, ::IPropertyTree *pSchemaRoot = NULL) : CXSDNodeBase::CXSDNodeBase(pParentNode, XSD_ENUMERATION_ARRAY), m_pSchemaRoot(pSchemaRoot)
+    {
+    }
+    virtual ~CEnumerationArray()
+    {
+    }
+    virtual void dump(::std::ostream &cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const;
+    virtual const char* getXML(const char* /*pComponent*/);
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+    int getEnvValueNodeIndex() const;
+    void setEnvValueNodeIndex(int index);
+    static CEnumerationArray* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath = NULL);
+
+protected:
+
+    ::IPropertyTree *m_pSchemaRoot;
+
+private:
+
+    CEnumerationArray() : CXSDNodeBase::CXSDNodeBase(NULL, XSD_ENUMERATION_ARRAY)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_ENUMERATION_HPP_

+ 97 - 0
configuration/configurator/SchemaExtension.cpp

@@ -0,0 +1,97 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "XMLTags.h"
+#include "jptree.hpp"
+#include "SchemaExtension.hpp"
+#include "SchemaComplexType.hpp"
+#include "SchemaSchema.hpp"
+#include "ConfigSchemaHelper.hpp"
+
+using namespace CONFIGURATOR;
+
+#define IPropertyTree ::IPropertyTree
+
+static const char* DEFAULT_ENVIRONMENT_XSD("Environment.xsd");
+
+void CExtension::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_EXTENSION_STR, offset);
+    QUICK_OUT(cout, Base, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+
+    if (this->getBaseNode() != NULL)
+        this->getBaseNode()->dump(cout, offset);
+
+    QuickOutFooter(cout, XSD_EXTENSION_STR, offset);
+}
+
+const char* CExtension::getXML(const char* /*pComponent*/)
+{
+    if (m_strXML.length() == 0 && m_pXSDNode != NULL)
+        m_pXSDNode->getXML(NULL);
+
+    return NULL;
+}
+
+void CExtension::initExtension()
+{
+    NODE_TYPES eNodeType[] = { XSD_SIMPLE_TYPE, XSD_SIMPLE_CONTENT };
+
+    const CXSDNodeBase *pBaseNode = (dynamic_cast<const CXSDNodeBase*>(this));
+
+    if (pBaseNode != NULL)
+    {
+        pBaseNode->getNodeByTypeAndNameAscending( eNodeType, this->getBase());
+        this->setBaseNode(const_cast<CXSDNodeBase*>(pBaseNode));
+    }
+}
+
+CExtension* CExtension::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    CHECK_EXCLUSION(XSD_EXTENSION);
+    assert(pSchemaRoot != NULL);
+
+    if (pSchemaRoot == NULL)
+        return NULL;
+
+    CExtension *pExtension = NULL;
+
+    if (xpath && *xpath)
+    {
+        IPropertyTree* pTree = pSchemaRoot->queryPropTree(xpath);
+
+        if (pTree == NULL)
+            return NULL; // no xs:extension node
+
+        const char* pBase = pSchemaRoot->getPropTree(xpath)->queryProp(XML_ATTR_BASE);
+
+        if (pBase != NULL)
+        {
+            pExtension = new CExtension(pParentNode);
+            pExtension->setXSDXPath(xpath);
+            pExtension->setBase(pBase);
+        }
+    }
+
+    if (pExtension != NULL)
+        CConfigSchemaHelper::getInstance()->addExtensionToBeProcessed(pExtension);
+
+    return pExtension;
+}

+ 62 - 0
configuration/configurator/SchemaExtension.hpp

@@ -0,0 +1,62 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_EXTENSION_HPP_
+#define _SCHEMA_EXTENSION_HPP_
+
+#include "SchemaCommon.hpp"
+#include "jstring.hpp"
+
+namespace CONFIGURATOR
+{
+
+class IPropertyTree;
+
+class CExtension : public CXSDNodeWithBase
+{
+public:
+
+    virtual ~CExtension()
+    {
+    }
+
+    virtual const char* getXML(const char* /*pComponent*/);
+    virtual void initExtension();
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+
+    virtual void getDocumentation(StringBuffer &strDoc) const
+    {
+       throwUnexpected(); // Should not be called directly
+    }
+
+    static CExtension* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath = NULL);
+
+protected:
+
+    CExtension(CXSDNodeBase* pParentNode, const char* pBase = NULL, CXSDNode *pXSDNode = NULL) : CXSDNodeWithBase::CXSDNodeWithBase(pParentNode, XSD_EXTENSION)
+    {
+    }
+
+private:
+
+    CExtension() : CXSDNodeWithBase::CXSDNodeWithBase(NULL, XSD_EXTENSION)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_EXTENSION_HPP_

+ 137 - 0
configuration/configurator/SchemaField.cpp

@@ -0,0 +1,137 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaField.hpp"
+
+using namespace CONFIGURATOR;
+
+#define IPropertyTree ::IPropertyTree
+
+CField* CField::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    assert(pParentNode != NULL);
+    assert(pParentNode->getNodeType() == XSD_FIELD_ARRAY);
+
+    if (pSchemaRoot == NULL || pParentNode == NULL)
+    {
+        // TODO: Throw Exception
+        return NULL;
+    }
+
+    CField *pField = NULL;
+
+    if (xpath != NULL && *xpath != 0)
+    {
+        IPropertyTree* pTree = pSchemaRoot->queryPropTree(xpath);
+
+        if (pTree == NULL)
+            return NULL;
+
+        const char* pXPath = pSchemaRoot->getPropTree(xpath)->queryProp(XML_ATTR_XPATH);
+        assert(pXPath != NULL && *pXPath != 0);
+
+        if (pXPath == NULL || *pXPath == 0)
+        {
+            assert(!"Throw Exception");
+            // TODO: throw exception
+        }
+
+        if (pXPath != NULL)
+        {
+            pField = new CField(pParentNode);
+            pField->setXSDXPath(xpath);
+            pField->setXPath(pXPath);
+        }
+        else
+        {
+            assert(!"xpath can not be be empty!");
+            // TODO: throw MakeExceptionFromMap(EX_STR_MISSING_XPATH_IN_FIELD);
+        }
+
+        const char *pID = pSchemaRoot->getPropTree(xpath)->queryProp(XML_ATTR_ID);
+
+        if (pID != NULL)
+            pField->setID(pID);
+   }
+   return pField;
+}
+
+void CField::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset += STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_FIELD_STR, offset);
+    QUICK_OUT(cout, XPath, offset);
+    QUICK_OUT(cout, ID, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QuickOutFooter(cout, XSD_FIELD_STR, offset);
+}
+
+CFieldArray* CFieldArray::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(xpath != NULL);
+    assert(pParentNode != NULL);
+    assert(pSchemaRoot != NULL);
+    assert(pParentNode->getNodeType() == XSD_KEY || pParentNode->getNodeType() == XSD_KEYREF || pParentNode->getNodeType() == XSD_UNIQUE);
+
+    if (pSchemaRoot == NULL || xpath == NULL || pParentNode == NULL)
+    {
+        // TODO: exceptions
+        //throw
+        return NULL;
+    }
+
+    StringBuffer strXPathExt(xpath);
+    CFieldArray *pFieldArray = new CFieldArray(pParentNode);
+    pFieldArray->setXSDXPath(xpath);
+
+    Owned<IPropertyTreeIterator> attributeIter = pSchemaRoot->getElements(xpath, ipt_ordered);
+
+    int count = 1;
+    ForEach(*attributeIter)
+    {
+        strXPathExt.clear().append(xpath).appendf("[%d]",count);
+
+        CField *pField = CField::load(pFieldArray, pSchemaRoot, strXPathExt.str());
+
+        if (pField != NULL)
+                pFieldArray->append(*pField);
+
+        count++;
+    }
+
+    if (pFieldArray->length() == 0)
+    {
+        delete pFieldArray;
+        pFieldArray = NULL;
+    }
+    return pFieldArray;
+}
+
+void CFieldArray::dump(::std::ostream &cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_FIELD_ARRAY_STR, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QUICK_OUT(cout, EnvXPath,  offset);
+    QUICK_OUT_ARRAY(cout, offset);
+    QuickOutFooter(cout, XSD_FIELD_ARRAY_STR, offset);
+}
+
+

+ 110 - 0
configuration/configurator/SchemaField.hpp

@@ -0,0 +1,110 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_FIELD_HPP_
+#define _SCHEMA_FIELD_HPP_
+
+#include "SchemaCommon.hpp"
+#include "jstring.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CSchemaField;
+class CKey;
+
+class CField : public CXSDNode
+{
+public:
+
+    virtual ~CField()
+    {
+    }
+
+    virtual void dump(::std::ostream &cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const
+    {
+        UNIMPLEMENTED;
+    }
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1)
+    {
+        UNIMPLEMENTED;
+    }
+
+    static CField* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+    GETTERSETTER(ID)
+    SETTER(XPath)
+
+    const char* getXPath(bool bRemoveAmpersand = true) const
+    {
+        if (bRemoveAmpersand == true)
+        {
+            static ::StringBuffer strRetString(m_strXPath);
+            static bool bOnce = true;
+
+            if (bOnce == true)
+                strRetString.remove(0,1);
+
+            return strRetString;
+        }
+        else
+            return m_strXPath.str();
+    }
+
+
+protected:
+
+    CField(CXSDNodeBase *pParentNode) : CXSDNode::CXSDNode(pParentNode, XSD_FIELD)
+    {
+    }
+
+    ::StringBuffer m_strXPath;
+};
+
+class CFieldArray : public ::CIArrayOf<CField>, public InterfaceImpl, public CXSDNodeBase
+{
+public:
+    virtual ~CFieldArray()
+    {
+    }
+
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const
+    {
+        UNIMPLEMENTED;
+    }
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1)
+    {
+        UNIMPLEMENTED;
+    }
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree)
+    {
+        UNIMPLEMENTED;
+    }
+
+    static CFieldArray* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+protected:
+
+    CFieldArray(CXSDNodeBase* pParentNode = NULL) : CXSDNodeBase::CXSDNodeBase(pParentNode, XSD_FIELD_ARRAY)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_FIELD_HPP_

+ 74 - 0
configuration/configurator/SchemaFractionDigits.cpp

@@ -0,0 +1,74 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "XMLTags.h"
+#include "jptree.hpp"
+#include <cstdlib>
+
+#include "SchemaFractionDigits.hpp"
+
+using namespace CONFIGURATOR;
+
+#define IPropertyTree ::IPropertyTree
+
+CFractionDigits* CFractionDigits::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    if (pSchemaRoot == NULL)
+        return NULL;
+
+    CFractionDigits *pFractionDigits = new CFractionDigits(pParentNode);
+    pFractionDigits->setXSDXPath(xpath);
+
+    if (xpath != NULL && *xpath != 0)
+    {
+        IPropertyTree* pTree = pSchemaRoot->queryPropTree(xpath);
+
+        if (pTree == NULL)
+            return pFractionDigits;
+
+        const char* pValue = pTree->queryProp(XML_ATTR_VALUE);
+
+        if (pValue != NULL && *pValue != 0)
+        {
+            pFractionDigits->setFractionDigits(pValue);
+            pFractionDigits->setValue(pValue);
+        }
+
+        if (pFractionDigits->getFractionDigits() < 0)  // not set or bad length value
+        {
+            delete pFractionDigits;
+            pFractionDigits = NULL;
+
+            //throw MakeExceptionFromMap(EX_STR_LENGTH_VALUE_MUST_BE_GREATER_THAN_OR_EQUAL_TO_ZERO, EACTION_FRACTION_DIGITS_HAS_BAD_LENGTH);
+            assert(false);
+        }
+    }
+    return pFractionDigits;
+}
+
+void CFractionDigits::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_FRACTION_DIGITS_STR, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QUICK_OUT(cout, EnvXPath,  offset);
+    QUICK_OUT(cout, Value, offset);
+    QUICK_OUT(cout, FractionDigits, offset);
+    QuickOutFooter(cout, XSD_FRACTION_DIGITS_STR, offset);
+}

+ 60 - 0
configuration/configurator/SchemaFractionDigits.hpp

@@ -0,0 +1,60 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_FRACTION_DIGITS_HPP_
+#define _SCHEMA_FRACTION_DIGITS_HPP_
+
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CFractionDigits : public CXSDNode
+{
+public:
+
+    virtual ~CFractionDigits()
+    {
+    }
+
+    static CFractionDigits* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const
+    {
+        UNIMPLEMENTED;
+    }
+    virtual const char* getXML(const char* /*pComponent*/)
+    {
+        UNIMPLEMENTED;
+        return NULL;
+    }
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1)
+    {
+        UNIMPLEMENTED;
+    }
+    GETTERSETTER(Value)
+    GETTERSETTERINT(FractionDigits)
+
+private:
+
+    CFractionDigits(CXSDNodeBase* pParentNode = NULL) : CXSDNode::CXSDNode(pParentNode, XSD_FRACTION_DIGITS), m_strValue(""), m_nFractionDigits(-1)
+    {
+    }
+};
+}
+#endif

+ 152 - 0
configuration/configurator/SchemaInclude.cpp

@@ -0,0 +1,152 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jptree.hpp"
+#include "XMLTags.h"
+#include "SchemaInclude.hpp"
+#include "SchemaSchema.hpp"
+#include "ConfigSchemaHelper.hpp"
+
+using namespace CONFIGURATOR;
+
+#define IPropertyTree ::IPropertyTree
+
+void CInclude::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_INCLUDE_STR, offset);
+    QUICK_OUT(cout, SchemaLocation, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+
+    if (this->getIncludeSchema() != NULL)
+        this->getIncludeSchema()->dump(cout, offset);
+
+    QuickOutFooter(cout, XSD_INCLUDE_STR, offset);
+}
+
+void CInclude::getDocumentation(StringBuffer &strDoc) const
+{
+}
+
+const char* CInclude::getXML(const char* /*pComponent*/)
+{
+    return m_strXML.str();
+}
+
+CInclude* CInclude::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    //return NULL; // TODO: Fix this to properly work with includes... temporary for testing
+
+    if (pParentNode == NULL || pSchemaRoot == NULL || xpath == NULL)
+        return NULL;
+
+    CInclude *pInclude = NULL;
+    IPropertyTree *pTree = pSchemaRoot->queryPropTree(xpath);
+
+    if (pTree != NULL)
+    {
+        const char *pSchemaLocation = pSchemaRoot->queryPropTree(xpath)->queryProp(XML_ATTR_SCHEMA_LOCATION);
+
+        if (pSchemaLocation != NULL)
+        {
+            CSchema* pSchema = CSchema::load(pSchemaLocation, NULL); // no parent across XSD files
+
+            pInclude = new CInclude(NULL, pSchemaLocation);
+            pInclude->setXSDXPath(xpath);
+            pInclude->setIncludedSchema(pSchema);
+        }
+    }
+    return pInclude;
+}
+
+void CInclude::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    assert(this->m_pIncludedSchema != NULL);
+    this->m_pIncludedSchema->populateEnvXPath(strXPath.str());
+}
+
+
+void CIncludeArray::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    //this->setEnvXPath(strXPath);
+    //strXPath.clear();
+    //QUICK_ENV_XPATH_WITH_INDEX(strXPath, index);
+}
+
+CIncludeArray* CIncludeArray::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char *xpath)
+{
+    if (pSchemaRoot == NULL)
+        return NULL;
+
+    CIncludeArray *pIncludeArray = new CIncludeArray(pParentNode);
+    pIncludeArray->setXSDXPath(xpath);
+
+    Owned<IPropertyTreeIterator> elemIter = pSchemaRoot->getElements(xpath);
+
+    int count = 1;
+
+    ForEach(*elemIter)
+    {
+        StringBuffer strXPathExt(xpath);
+        strXPathExt.appendf("[%d]", count);
+
+        CInclude *pInclude = CInclude::load(pIncludeArray, pSchemaRoot, strXPathExt.str());
+
+        if (pInclude != NULL)
+            pIncludeArray->append(*pInclude);
+
+        count++;
+    }
+
+    if (pIncludeArray->length() == 0)
+        return NULL;
+
+    return pIncludeArray;
+}
+
+const char* CIncludeArray::getXML(const char* /*pComponent*/)
+{
+    if (m_strXML.length() == 0)
+    {
+        int length = this->length();
+
+        for (int idx = 0; idx < length; idx++)
+        {
+            CInclude &Include = this->item(idx);
+            m_strXML.append(Include.getXML(NULL));
+
+            if (idx+1 < length)
+                m_strXML.append("\n");
+        }
+    }
+    return m_strXML.str();
+}
+
+void CIncludeArray::dump(::std::ostream &cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_INCLUDE_ARRAY_STR, offset);
+    QUICK_OUT_ARRAY(cout, offset);
+    QuickOutFooter(cout, XSD_INCLUDE_ARRAY_STR, offset);
+}
+
+void CIncludeArray::getDocumentation(StringBuffer &strDoc) const
+{
+    QUICK_DOC_ARRAY(strDoc);
+}

+ 104 - 0
configuration/configurator/SchemaInclude.hpp

@@ -0,0 +1,104 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_INCLUDE_HPP_
+#define _SCHEMA_INCLUDE_HPP_
+
+#include "jstring.hpp"
+#include "jarray.hpp"
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CSchema;
+
+class CInclude : public CXSDNode
+{
+public:
+
+    virtual ~CInclude()
+    {
+    }
+
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(StringBuffer &strDoc) const;
+    virtual const char* getXML(const char* /*pComponent*/);
+    virtual void populateEnvXPath(StringBuffer strXPath, unsigned int index = 1);
+
+    GETTERSETTER(SchemaLocation)
+
+    const CSchema* getIncludeSchema() const
+    {
+        return m_pIncludedSchema;
+    }
+
+    static CInclude* load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath = NULL);
+
+protected:
+
+    CInclude(CXSDNodeBase* pParentNode, const char* pSchemaLocation = NULL) : CXSDNode::CXSDNode(pParentNode, XSD_INCLUDE), m_strSchemaLocation(pSchemaLocation)
+    {
+    }
+
+    CSchema *m_pIncludedSchema;
+
+    void setIncludedSchema(CSchema *pSchema)
+    {
+        m_pIncludedSchema = pSchema;
+    }
+
+private:
+
+    CInclude(CXSDNodeBase* pParentNode = NULL) : CXSDNode::CXSDNode(pParentNode, XSD_INCLUDE), m_pIncludedSchema(NULL)
+    {
+    }
+
+};
+
+class CIncludeArray : public CIArrayOf<CInclude>, public InterfaceImpl, public CXSDNodeBase
+{
+public:
+
+    CIncludeArray(CXSDNodeBase* pParentNode, IPropertyTree *pSchemaRoot) : CXSDNodeBase::CXSDNodeBase(pParentNode, XSD_INCLUDE_ARRAY), m_pSchemaRoot(pSchemaRoot)
+    {
+    }
+
+    virtual ~CIncludeArray()
+    {
+    }
+
+    virtual void dump(::std::ostream &cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(StringBuffer &strDoc) const;
+    virtual void populateEnvXPath(StringBuffer strXPath, unsigned int index = 1);
+    virtual const char* getXML(const char* /*pComponent*/);
+
+    static CIncludeArray* load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath);
+
+protected:
+
+    IPropertyTree *m_pSchemaRoot;
+
+private:
+
+    CIncludeArray(CXSDNodeBase* pParentNode = NULL) : CXSDNodeBase::CXSDNodeBase(pParentNode, XSD_INCLUDE_ARRAY)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_INCLUDE_HPP_

+ 222 - 0
configuration/configurator/SchemaKey.cpp

@@ -0,0 +1,222 @@
+/*##############################################################################
+ *
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jptree.hpp"
+#include "SchemaKey.hpp"
+#include "SchemaSelector.hpp"
+#include "SchemaField.hpp"
+#include "SchemaAnnotation.hpp"
+#include "SchemaCommon.hpp"
+#include "ConfigSchemaHelper.hpp"
+#include "SchemaMapManager.hpp"
+#include "SchemaAttributes.hpp"
+
+using namespace CONFIGURATOR;
+
+#define IPropertyTree ::IPropertyTree
+
+CKey* CKey::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    assert(pParentNode != NULL);
+    assert(pParentNode->getNodeType() == XSD_KEY_ARRAY);
+
+    if (pSchemaRoot == NULL || pParentNode == NULL)
+    {
+        // TODO: Throw Exception
+        return NULL;
+    }
+
+    CKey *pKey = new CKey(pParentNode);
+
+    if (xpath != NULL && *xpath != 0)
+    {
+        IPropertyTree* pTree = pSchemaRoot->queryPropTree(xpath);
+
+        if (pTree == NULL)
+            return NULL; // no xs:key
+
+        const char* pName = pSchemaRoot->getPropTree(xpath)->queryProp(XML_ATTR_NAME);
+        if (pName != NULL)
+         {
+             pKey = new CKey(pParentNode);
+             pKey->setXSDXPath(xpath);
+             pKey->setName(pName);
+         }
+         else
+         {
+             assert(!"value attribute can be empty!");
+             // TODO: throw MakeExceptionFromMap(EX_STR_MISSING_VALUE_ATTRIBUTE_IN_LENGTH);
+             return NULL;
+         }
+
+         const char *pID = pSchemaRoot->getPropTree(xpath)->queryProp(XML_ATTR_ID);
+         if (pID != NULL)
+             pKey->setID(pID);
+
+         StringBuffer strXPathExt(xpath);
+         strXPathExt.append("/").append(XSD_TAG_FIELD);
+
+         if (strXPathExt.charAt(0) == '@')
+             strXPathExt.remove(0,1); // remove '@'
+
+         pKey->m_pFieldArray = CFieldArray::load(pKey, pSchemaRoot, strXPathExt.str());
+
+         strXPathExt.clear().set(xpath);
+         strXPathExt.append("/").append(XSD_TAG_SELECTOR);
+
+         if (strXPathExt.charAt(0) == '.')
+             strXPathExt.remove(0,2); // remove leading ./
+
+         pKey->m_pSelector = CSelector::load(pKey, pSchemaRoot, strXPathExt.str());
+         assert(pKey->m_pFieldArray != NULL && pKey->m_pSelector != NULL);
+
+         strXPathExt.append("/").append(XSD_TAG_ANNOTATION);
+         pKey->m_pAnnotation = CAnnotation::load(pKey, pSchemaRoot, strXPathExt.str());
+    }
+    return pKey;
+}
+
+void CKey::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    assert(this->m_pSelector != NULL);
+
+    this->setEnvXPath(strXPath.str());
+
+    if (this->m_pSelector != NULL)
+    {
+        this->m_pSelector->populateEnvXPath(strXPath.str());
+        CConfigSchemaHelper::getInstance()->addKeyForReverseAssociation(this);
+    }
+}
+
+bool CKey::checkConstraint(const char *pValue) const
+{
+    bool bRetVal = true;
+
+    if (m_pSelector != NULL && m_pFieldArray->length() != 0)
+    {
+        for (int idx = 0; idx < m_pFieldArray->length(); idx++)
+        {
+            assert(!"Multiple fields not implemented");
+            CField *m_pField = &(m_pFieldArray->item(idx));
+
+            assert(m_pField != NULL);
+            if (m_pField == NULL)
+                return false;
+
+            StringBuffer strXPathForConstraintCheck(this->getEnvXPath());
+            strXPathForConstraintCheck.appendf("/%s", this->m_pSelector->getXPath());
+
+            const CElement *pElement = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getElementFromXPath(strXPathForConstraintCheck.str());
+            if (pElement == NULL)
+                return false;
+
+            const CAttribute *pAttribute = dynamic_cast<const CAttribute*>(pElement->getNodeByTypeAndNameDescending(XSD_ATTRIBUTE, m_pField->getXPath()));  // needs to be first possible descendent
+            if (pAttribute != NULL && pAttribute->getParentNodeByType(XSD_ELEMENT) != pElement)
+            {
+                assert(!"Could not find match for key");
+            }
+        }
+    }
+    return bRetVal;
+}
+
+void CKey::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset += STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_KEY_STR, offset);
+    QUICK_OUT(cout, Name, offset);
+    QUICK_OUT(cout, ID, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+
+    if (m_pFieldArray != NULL)
+        m_pFieldArray->dump(cout, offset);
+    if (m_pSelector != NULL)
+        m_pSelector->dump(cout, offset);
+
+    QuickOutFooter(cout, XSD_KEY_STR, offset);
+}
+
+CKeyArray* CKeyArray::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    assert(pParentNode->getNodeType() == XSD_ELEMENT);
+
+    if (pSchemaRoot == NULL || xpath == NULL)
+        return NULL;
+
+    StringBuffer strXPathExt(xpath);
+
+    CKeyArray *pKeyArray = new CKeyArray(pParentNode);
+    pKeyArray->setXSDXPath(xpath);
+
+    Owned<IPropertyTreeIterator> attributeIter = pSchemaRoot->getElements(xpath, ipt_ordered);
+
+    int count = 1;
+    ForEach(*attributeIter)
+    {
+        strXPathExt.clear().append(xpath).appendf("[%d]",count);
+
+        CKey *pKey = CKey::load(pKeyArray, pSchemaRoot, strXPathExt.str());
+        if (pKey != NULL)
+            pKeyArray->append(*pKey);
+
+        count++;
+    }
+
+    if (pKeyArray->length() == 0)
+    {
+        delete pKeyArray;
+        pKeyArray = NULL;
+    }
+    return pKeyArray;
+}
+
+bool CKeyArray::checkConstraint(const char *pValue) const
+{
+    assert(pValue != NULL);
+
+    if (pValue == NULL)
+        return false;
+
+    for (int idx = 0; idx < this->length(); idx++)
+    {
+        if ((this->item(idx)).checkConstraint(pValue) == false)
+            return false;
+    }
+    return true;
+}
+
+void CKeyArray::dump(::std::ostream &cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_KEY_ARRAY_STR, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QUICK_OUT(cout, EnvXPath,  offset);
+    QUICK_OUT_ARRAY(cout, offset);
+    QuickOutFooter(cout, XSD_KEY_ARRAY_STR, offset);
+}
+
+void CKeyArray::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    this->setEnvXPath(strXPath);
+    QUICK_ENV_XPATH_WITH_INDEX(strXPath, index)
+}

+ 102 - 0
configuration/configurator/SchemaKey.hpp

@@ -0,0 +1,102 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_KEY_HPP_
+#define _SCHEMA_KEY_HPP_
+
+#include "SchemaCommon.hpp"
+#include "jstring.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CSelector;
+class CFieldArray;
+class CAnnotation;
+
+class CKey : public CXSDNode
+{
+    friend class CKeyArray;
+    friend class CKeyRef;
+
+public:
+
+    virtual ~CKey()
+    {
+    }
+
+    virtual void dump(::std::ostream &cout, unsigned int offset = 0) const;
+    virtual void populateEnvXPath(StringBuffer strXPath, unsigned int index = 1);
+    virtual void getDocumentation(StringBuffer &strDoc) const
+    {
+        UNIMPLEMENTED;
+    }
+
+    const CAnnotation* getAnnotation() const
+    {
+        return m_pAnnotation;
+    }
+    static CKey* load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath);
+
+    GETTERSETTER(Name)
+    GETTERSETTER(ID)
+
+protected:
+
+    CKey(CXSDNodeBase* pParentNode) : CXSDNode::CXSDNode(pParentNode, XSD_KEY), m_pFieldArray(NULL), m_pSelector(NULL), m_pAnnotation(NULL)
+    {
+    }
+
+    virtual bool checkConstraint(const char *pValue) const;
+
+    CFieldArray *m_pFieldArray;
+    CSelector *m_pSelector;
+    CAnnotation *m_pAnnotation;
+};
+
+class CKeyArray : public CIArrayOf<CKey>, public InterfaceImpl, public CXSDNodeBase
+{
+public:
+
+    virtual ~CKeyArray()
+    {
+    }
+
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void populateEnvXPath(StringBuffer strXPath, unsigned int index = 1);
+
+    virtual void getDocumentation(StringBuffer &strDoc) const
+    {
+        UNIMPLEMENTED;
+    }
+    virtual void loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+    {
+        UNIMPLEMENTED;
+    }
+    virtual bool checkConstraint(const char *pValue) const;
+
+    static CKeyArray* load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath);
+
+protected:
+
+    CKeyArray(CXSDNodeBase* pParentNode = NULL) : CXSDNodeBase::CXSDNodeBase(pParentNode, XSD_KEY_ARRAY)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_KEY_HPP_

+ 178 - 0
configuration/configurator/SchemaKeyRef.cpp

@@ -0,0 +1,178 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaCommon.hpp"
+#include "SchemaSelector.hpp"
+#include "ConfigSchemaHelper.hpp"
+#include "SchemaMapManager.hpp"
+#include "SchemaKeyRef.hpp"
+
+using namespace CONFIGURATOR;
+
+#define IPropertyTree ::IPropertyTree
+#define StringBuffer ::StringBuffer
+
+CKeyRef* CKeyRef::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    assert(pParentNode != NULL);
+    assert(pParentNode->getNodeType() == XSD_KEYREF_ARRAY);
+
+    if (pSchemaRoot == NULL || pParentNode == NULL)
+    {
+        // TODO: Throw Exception
+        return NULL;
+    }
+
+    CKeyRef *pKeyRef = new CKeyRef(pParentNode);
+
+    if (xpath != NULL && *xpath != 0)
+    {
+        IPropertyTree* pTree = pSchemaRoot->queryPropTree(xpath);
+        if (pTree == NULL)
+            return NULL; // no xs:KeyRef
+
+        const char* pName = pSchemaRoot->getPropTree(xpath)->queryProp(XML_ATTR_NAME);
+        const char* pRefer = pSchemaRoot->getPropTree(xpath)->queryProp(XML_ATTR_REFER);
+
+        if (pName != NULL && pRefer != NULL)
+        {
+            pKeyRef = new CKeyRef(pParentNode);
+            pKeyRef->setXSDXPath(xpath);
+            pKeyRef->setName(pName);
+        }
+        else
+        {
+            assert(!"value attribute can be empty!");
+            // TODO: throw MakeExceptionFromMap(EX_STR_MISSING_VALUE_ATTRIBUTE_IN_LENGTH);
+        }
+
+        const char *pID = pSchemaRoot->getPropTree(xpath)->queryProp(XML_ATTR_ID);
+        if (pID != NULL)
+            pKeyRef->setID(pID);
+
+        StringBuffer strXPathExt(xpath);
+        strXPathExt.append("/").append(XSD_TAG_FIELD);
+        pKeyRef->m_pFieldArray = CFieldArray::load(pKeyRef, pSchemaRoot, strXPathExt.str());
+
+        strXPathExt.clear().set(xpath);
+        strXPathExt.append("/").append(XSD_TAG_SELECTOR);
+        pKeyRef->m_pSelector = CSelector::load(pKeyRef, pSchemaRoot, strXPathExt.str());
+    }
+    return pKeyRef;
+}
+
+void CKeyRef::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset += STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_KEYREF_STR, offset);
+    QUICK_OUT(cout, Name, offset);
+    QUICK_OUT(cout, ID, offset);
+    QUICK_OUT(cout, Refer, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+
+    if (m_pFieldArray != NULL)
+        m_pFieldArray->dump(cout, offset);
+
+    if (m_pSelector != NULL)
+        m_pSelector->dump(cout, offset);
+
+    QuickOutFooter(cout, XSD_KEYREF_STR, offset);
+}
+
+bool CKeyRef::checkConstraint(const char *pValue) const
+{
+    assert (pValue != NULL);
+
+    if (pValue == NULL)
+        return true;
+    else
+    {
+        StringBuffer strQName(this->getXSDXPath());
+        strQName.append("/").append(this->getRefer());
+
+        CKey *pKey = CConfigSchemaHelper::getInstance()->getSchemaMapManager()->getKeyFromXSDXPath(strQName.str());
+        return pKey->checkConstraint(pValue);
+    }
+}
+
+void CKeyRef::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    assert(this->m_pSelector != NULL);
+
+    this->setEnvXPath(strXPath.str());
+
+    if (this->m_pSelector != NULL)
+    {
+        this->m_pSelector->populateEnvXPath(strXPath.str());
+        CConfigSchemaHelper::getInstance()->addKeyRefForReverseAssociation(this);
+    }
+}
+
+CKeyRefArray* CKeyRefArray::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    assert(pParentNode->getNodeType() == XSD_ELEMENT);
+
+    if (pSchemaRoot == NULL || xpath == NULL)
+        return NULL;
+
+    StringBuffer strXPathExt(xpath);
+
+    CKeyRefArray *pKeyRefArray = new CKeyRefArray(pParentNode);
+    pKeyRefArray->setXSDXPath(xpath);
+
+    Owned<IPropertyTreeIterator> attributeIter = pSchemaRoot->getElements(xpath, ipt_ordered);
+
+    int count = 1;
+    ForEach(*attributeIter)
+    {
+        strXPathExt.clear().append(xpath).appendf("[%d]",count);
+
+        CKeyRef *pKeyRef = CKeyRef::load(pKeyRefArray, pSchemaRoot, strXPathExt.str());
+
+        if (pKeyRef != NULL)
+            pKeyRefArray->append(*pKeyRef);
+
+        count++;
+    }
+
+    if (pKeyRefArray->length() == 0)
+    {
+        delete pKeyRefArray;
+        pKeyRefArray = NULL;
+    }
+    return pKeyRefArray;
+}
+
+void CKeyRefArray::dump(::std::ostream &cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_KEYREF_ARRAY_STR, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QUICK_OUT(cout, EnvXPath,  offset);
+    QUICK_OUT_ARRAY(cout, offset);
+    QuickOutFooter(cout, XSD_KEYREF_ARRAY_STR, offset);
+}
+
+void CKeyRefArray::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    this->setEnvXPath(strXPath);
+    QUICK_ENV_XPATH_WITH_INDEX(strXPath, index)
+}

+ 91 - 0
configuration/configurator/SchemaKeyRef.hpp

@@ -0,0 +1,91 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_KEYREF_HPP_
+#define _SCHEMA_KEYREF_HPP_
+
+#include "jstring.hpp"
+#include "SchemaCommon.hpp"
+
+class CSelector;
+class CFieldArray;
+
+namespace CONFIGURATOR
+{
+
+class CKeyRef : public CXSDNode
+{
+public:
+
+    virtual ~CKeyRef()
+    {
+    }
+
+    virtual void dump(::std::ostream &cout, unsigned int offset = 0) const;
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+    bool checkConstraint(const char *pValue) const;
+
+    virtual void getDocumentation(::StringBuffer &strDoc) const
+    {
+        UNIMPLEMENTED;
+    }
+
+    static CKeyRef* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+    GETTERSETTER(Name)
+    GETTERSETTER(ID)
+    GETTERSETTER(Refer)
+
+protected:
+
+    CKeyRef(CXSDNodeBase* pParentNode) : CXSDNode::CXSDNode(pParentNode, XSD_KEYREF), m_pFieldArray(NULL), m_pSelector(NULL)
+    {
+    }
+
+    CFieldArray *m_pFieldArray;
+    CSelector *m_pSelector;
+};
+
+class CKeyRefArray : public ::CIArrayOf<CKeyRef>, public InterfaceImpl, public CXSDNodeBase
+{
+public:
+    virtual ~CKeyRefArray()
+    {
+    }
+
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+
+    virtual void getDocumentation(::StringBuffer &strDoc) const
+    {
+        UNIMPLEMENTED;
+    }
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree)
+    {
+        UNIMPLEMENTED;
+    }
+    static CKeyRefArray* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+protected:
+
+    CKeyRefArray(CXSDNodeBase* pParentNode = NULL) : CXSDNodeBase::CXSDNodeBase(pParentNode, XSD_KEYREF_ARRAY)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_KeyRef_HPP_

+ 67 - 0
configuration/configurator/SchemaLength.cpp

@@ -0,0 +1,67 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jptree.hpp"
+#include "SchemaLength.hpp"
+#include "ConfigSchemaHelper.hpp"
+
+using namespace CONFIGURATOR;
+
+#define IPropertyTree ::IPropertyTree
+
+CLength* CLength::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    if (pSchemaRoot == NULL)
+        return NULL;
+
+    CLength *pLength = NULL;
+
+    if (xpath && *xpath)
+    {
+        IPropertyTree* pTree = pSchemaRoot->queryPropTree(xpath);
+        if (pTree == NULL)
+            return NULL; // no xs:length node
+
+        const char* pValue = pSchemaRoot->getPropTree(xpath)->queryProp(XML_ATTR_VALUE);
+        if (pValue != NULL)
+        {
+            if (atoi(pValue) < 0)
+                 throw MakeExceptionFromMap(EX_STR_MISSING_VALUE_ATTRIBUTE_IN_LENGTH);
+
+            pLength = new CLength(pParentNode);
+            pLength->setXSDXPath(xpath);
+            pLength->setValue(pValue);
+        }
+        else
+        {
+            assert(!"value attribute can be empty!");
+            throw MakeExceptionFromMap(EX_STR_MISSING_VALUE_ATTRIBUTE_IN_LENGTH);
+        }
+    }
+    return pLength;
+}
+
+void CLength::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset += STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_LENGTH_STR, offset);
+    QUICK_OUT(cout, Value, offset);
+    QuickOutFooter(cout, XSD_LENGTH_STR, offset);
+}
+

+ 59 - 0
configuration/configurator/SchemaLength.hpp

@@ -0,0 +1,59 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_LENGTH_HPP_
+#define _SCHEMA_LENGTH_HPP_
+
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CLength : public CXSDNode
+{
+public:
+
+    virtual ~CLength()
+    {
+    }
+    static CLength* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(StringBuffer &strDoc) const
+    {
+        UNIMPLEMENTED;
+    }
+    virtual const char* getXML(const char* /*pComponent*/)
+    {
+        UNIMPLEMENTED;
+        return NULL;
+    }
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1)
+    {
+        UNIMPLEMENTED;
+    }
+    GETTERSETTER(Value)
+    GETTERSETTERINT(Length)
+
+private:
+
+    CLength(CXSDNodeBase* pParentNode = NULL) : CXSDNode::CXSDNode(pParentNode, XSD_LENGTH), m_nLength(-1)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_LENGTH_HPP_

+ 593 - 0
configuration/configurator/SchemaMapManager.cpp

@@ -0,0 +1,593 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaMapManager.hpp"
+#include "SchemaAll.hpp"
+
+using namespace CONFIGURATOR;
+
+CSchemaMapManager::CSchemaMapManager()
+{
+    m_pSchemaPtrMap.setown(new MapStringToCSchema());
+    m_pSimpleTypePtrMap.setown(new MapStringToCSimpleType());
+    m_pComplexTypePtrsMap.setown (new MapStringToCComplexType);
+    m_pAttributeGroupTypePtrsMap.setown(new MapStringToCAttributeGroup);
+    m_pAttributePtrsMap.setown(new MapStringToCAttribute);
+    m_pRestrictionPtrsMap.setown(new MapStringToCRestriction);
+    m_pElementPtrsMap.setown(new MapStringToCElement);
+    m_pElementNamePtrsMap.setown(new MapStringToCElement);
+    m_pXSDToElementPtrsMap.setown(new MapStringToCElement);
+    m_pElementArrayPtrsMap.setown(new MapStringToCElementArray);
+    m_pStringToEnumMap.setown(new MapStringToNodeTypeEnum);
+    m_pStringToKeyPtrsMap.setown(new MapStringToCKey);
+    m_pStringToNodeBaseMap.setown(new MapStringToCNodeBase);
+
+    m_enumArray[XSD_DT_NORMALIZED_STRING][0] = XSD_DATA_TYPE_NORMALIZED_STRING;
+    m_enumArray[XSD_DT_NORMALIZED_STRING][1] = XSD_DT_NORMALIZED_STRING_STR;
+
+    m_enumArray[XSD_DT_STRING-XSD_DT_NORMALIZED_STRING][0] = XSD_DATA_TYPE_STRING;
+    m_enumArray[XSD_DT_STRING-XSD_DT_NORMALIZED_STRING][1] = XSD_DT_STRING_STR;
+
+    m_enumArray[XSD_DT_TOKEN-XSD_DT_NORMALIZED_STRING][0] = XSD_DATA_TYPE_TOKEN;
+    m_enumArray[XSD_DT_TOKEN-XSD_DT_NORMALIZED_STRING][1] = XSD_DT_TOKEN_STR;
+
+    m_enumArray[XSD_DT_DATE-XSD_DT_NORMALIZED_STRING][0] = XSD_DATA_TYPE_DATE;
+    m_enumArray[XSD_DT_DATE-XSD_DT_NORMALIZED_STRING][1] = XSD_DT_DATE_STR;
+
+    m_enumArray[XSD_DT_TIME-XSD_DT_NORMALIZED_STRING][0] = XSD_DATA_TYPE_TIME;
+    m_enumArray[XSD_DT_TIME-XSD_DT_NORMALIZED_STRING][1] = XSD_DT_TIME_STR;
+
+    m_enumArray[XSD_DT_DATE_TIME-XSD_DT_NORMALIZED_STRING][0] = XSD_DATA_TYPE_DATE_TIME;
+    m_enumArray[XSD_DT_DATE_TIME-XSD_DT_NORMALIZED_STRING][1] = XSD_DT_DATE_TIME_STR;
+
+    m_enumArray[XSD_DT_DECIMAL-XSD_DT_NORMALIZED_STRING][0] = XSD_DATA_TYPE_DECIMAL;
+    m_enumArray[XSD_DT_DECIMAL-XSD_DT_NORMALIZED_STRING][1] = XSD_DT_DECIMAL_STR;
+
+    m_enumArray[XSD_DT_INTEGER-XSD_DT_NORMALIZED_STRING][0] = XSD_DATA_TYPE_INTEGER;
+    m_enumArray[XSD_DT_INTEGER-XSD_DT_NORMALIZED_STRING][1] = XSD_DT_INTEGER_STR;
+
+    m_enumArray[XSD_DT_INT-XSD_DT_NORMALIZED_STRING][0] = XSD_DATA_TYPE_INT;
+    m_enumArray[XSD_DT_INT-XSD_DT_NORMALIZED_STRING][1] = XSD_DT_INT_STR;
+
+    m_enumArray[XSD_DT_LONG-XSD_DT_NORMALIZED_STRING][0] = XSD_DATA_TYPE_NORMALIZED_STRING;
+    m_enumArray[XSD_DT_LONG-XSD_DT_NORMALIZED_STRING][1] = XSD_DT_LONG_STR;
+
+    m_enumArray[XSD_DT_NON_NEG_INTEGER-XSD_DT_NORMALIZED_STRING][0] = XSD_DATA_TYPE_NORMALIZED_STRING;
+    m_enumArray[XSD_DT_NON_NEG_INTEGER-XSD_DT_NORMALIZED_STRING][1] = XSD_DT_NON_NEG_INTEGER_STR;
+
+    m_enumArray[XSD_DT_NON_POS_INTEGER-XSD_DT_NORMALIZED_STRING][0] = XSD_DATA_TYPE_NORMALIZED_STRING;
+    m_enumArray[XSD_DT_NON_POS_INTEGER-XSD_DT_NORMALIZED_STRING][1] = XSD_DT_NON_POS_INTEGER_STR;
+
+    m_enumArray[XSD_DT_POS_INTEGER-XSD_DT_NORMALIZED_STRING][0] = XSD_DATA_TYPE_NORMALIZED_STRING;
+    m_enumArray[XSD_DT_POS_INTEGER-XSD_DT_NORMALIZED_STRING][1] = XSD_DT_POS_INTEGER_STR;
+
+    m_enumArray[XSD_DT_NEG_INTEGER-XSD_DT_NORMALIZED_STRING][0] = XSD_DATA_TYPE_NORMALIZED_STRING;
+    m_enumArray[XSD_DT_NEG_INTEGER-XSD_DT_NORMALIZED_STRING][1] = XSD_DT_NEG_INTEGER_STR;
+
+    m_enumArray[XSD_DT_BOOLEAN-XSD_DT_NORMALIZED_STRING][0] = XSD_DATA_TYPE_BOOLEAN;
+    m_enumArray[XSD_DT_BOOLEAN-XSD_DT_NORMALIZED_STRING][1] = XSD_DT_BOOLEAN_STR;
+
+    m_pStringToEnumMap->setValue(XSD_DATA_TYPE_NORMALIZED_STRING, XSD_DT_NORMALIZED_STRING);
+    m_pStringToEnumMap->setValue(XSD_DATA_TYPE_STRING, XSD_DT_STRING);
+    m_pStringToEnumMap->setValue(XSD_DATA_TYPE_TOKEN, XSD_DT_TOKEN);
+    m_pStringToEnumMap->setValue(XSD_DATA_TYPE_DATE, XSD_DT_DATE);
+    m_pStringToEnumMap->setValue(XSD_DATA_TYPE_TIME, XSD_DT_TIME);
+    m_pStringToEnumMap->setValue(XSD_DATA_TYPE_DATE_TIME, XSD_DT_DATE_TIME);
+    m_pStringToEnumMap->setValue(XSD_DATA_TYPE_DECIMAL, XSD_DT_INTEGER);
+    m_pStringToEnumMap->setValue(XSD_DATA_TYPE_DECIMAL, XSD_DT_DECIMAL);
+    m_pStringToEnumMap->setValue(XSD_DATA_TYPE_LONG, XSD_DT_LONG);
+    m_pStringToEnumMap->setValue(XSD_DATA_TYPE_NON_NEGATIVE_INTEGER, XSD_DT_NON_NEG_INTEGER);
+    m_pStringToEnumMap->setValue(XSD_DATA_TYPE_NON_POSITIVE_INTEGER, XSD_DT_NON_POS_INTEGER);
+    m_pStringToEnumMap->setValue(XSD_DATA_TYPE_NEGATIVE_INTEGER, XSD_DT_POS_INTEGER);
+    m_pStringToEnumMap->setValue(XSD_DATA_TYPE_POSITIVE_INTEGER, XSD_DT_NEG_INTEGER);
+    m_pStringToEnumMap->setValue(XSD_DATA_TYPE_BOOLEAN, XSD_DT_BOOLEAN);
+
+
+    // exclude node processing of types added here
+    addExludedNode(XSD_EXTENSION);
+}
+
+CSchemaMapManager::~CSchemaMapManager()
+{
+}
+
+CSchema* CSchemaMapManager::getSchemaForXSD(const char* pComponent)
+{
+    CSchema **pSchema = m_pSchemaPtrMap->getValue(pComponent);
+
+    if (pSchema != NULL )
+    {
+        assert ((*pSchema)->getLinkCount() == 1);
+        return *pSchema;
+    }
+    else
+        return NULL;
+}
+
+void CSchemaMapManager::setSchemaForXSD(const char* pComponent, CSchema *pSchema)
+{
+    assert(pSchema != NULL);
+    assert(pComponent != NULL);
+    assert(*pComponent != 0);
+
+    assert(pSchema->getLinkCount() == 1);
+
+    if (pSchema != NULL && pComponent != NULL && *pComponent != 0)
+    {
+        if (m_pSchemaPtrMap->getValue(pComponent) == NULL)
+            m_pSchemaPtrMap->setValue(pComponent, (pSchema));
+    }
+}
+
+CSimpleType* CSchemaMapManager::getSimpleTypeWithName(const char* pName)
+{
+    assert(pName != NULL);
+    if (pName == NULL)
+        return NULL;
+
+    CSimpleType **ppSimpleType = NULL;
+    ppSimpleType = m_pSimpleTypePtrMap->getValue(pName);
+
+    if (ppSimpleType != NULL)
+        return *ppSimpleType;
+    else
+        return NULL;
+}
+
+void CSchemaMapManager::setSimpleTypeWithName(const char* pName, CSimpleType *pSimpleType)
+{
+    assert (pSimpleType != NULL);
+    if (pName == NULL || pSimpleType == NULL)
+        return;
+    if (m_pSimpleTypePtrMap->getValue(pName) != NULL)
+        throw MakeExceptionFromMap(EX_STR_SIMPLE_TYPE_ALREADY_DEFINED);
+
+    assert(pSimpleType->getLinkCount() == 1);
+    m_pSimpleTypePtrMap->setValue(pName, pSimpleType);
+}
+
+CComplexType* CSchemaMapManager::getComplexTypeWithName(const char* pName)
+{
+    assert(pName != NULL);
+    if (pName == NULL)
+        return NULL;
+
+    CComplexType **ppComplexType = NULL;
+    ppComplexType = (m_pComplexTypePtrsMap->getValue(pName));
+
+    return (ppComplexType != NULL ? *ppComplexType : NULL);
+}
+
+void CSchemaMapManager::setComplexTypeWithName(const char* pName, CComplexType *pComplexType)
+{
+    assert (pComplexType != NULL);
+    if (pName == NULL || pComplexType == NULL)
+        return;
+
+    if (m_pComplexTypePtrsMap->getValue(pName) != NULL)
+        throw MakeExceptionFromMap(EX_STR_COMPLEX_TYPE_ALREADY_DEFINED);
+
+    assert(pComplexType->getLinkCount() == 1);
+    m_pComplexTypePtrsMap->setValue(pName, pComplexType);
+}
+
+CComplexType* CSchemaMapManager::getComplexTypeFromXPath(const char *pXPath)
+{
+    assert(pXPath != NULL && *pXPath != 0);
+
+    CComplexType** ppComplexType =  m_pComplexTypePtrsMap->getValue(pXPath);
+    if (ppComplexType != NULL)
+        return *ppComplexType;
+    else
+        return NULL;
+}
+
+CAttributeGroup* CSchemaMapManager::getAttributeGroup(const char* pName)
+{
+    assert(pName != NULL);
+    if (pName == NULL)
+        return NULL;
+
+    CAttributeGroup *pAttributeGroup = NULL;
+    pAttributeGroup = *(m_pAttributeGroupTypePtrsMap->getValue(pName));
+
+    assert(pAttributeGroup != NULL);
+    return pAttributeGroup;
+}
+
+void CSchemaMapManager::setAttributeGroupTypeWithName(const char* pName, CAttributeGroup *pAttributeGroup)
+{
+    assert (pAttributeGroup != NULL);
+    if (pName == NULL || pAttributeGroup == NULL)
+        return;
+
+    if (m_pAttributeGroupTypePtrsMap->getValue(pName) != NULL)
+    {
+        m_pAttributeGroupTypePtrsMap->remove(pName);
+        //throw MakeExceptionFromMap(EX_STR_ATTRIBUTE_GROUP_ALREADY_DEFINED);
+    }
+
+    assert(pAttributeGroup->getLinkCount() == 1);
+    m_pAttributeGroupTypePtrsMap->setValue(pName, pAttributeGroup);
+}
+
+CAttributeGroup* CSchemaMapManager::getAttributeGroupFromXPath(const char *pXPath)
+{
+    assert(pXPath != NULL && *pXPath != 0);
+    if (pXPath == NULL || *pXPath == 0)
+        return NULL;
+
+    CAttributeGroup **ppAttributeGroup = m_pAttributeGroupTypePtrsMap->getValue(pXPath);
+    assert(ppAttributeGroup != NULL);
+
+    if (ppAttributeGroup != NULL)
+        return *ppAttributeGroup;
+    else
+        return NULL;
+}
+
+CElement* CSchemaMapManager::getElementWithName(const char* pName)
+{
+    assert (pName != NULL && *pName != 0);
+    if (pName != NULL && *pName != 0)
+    {
+        CElement **ppElement = m_pElementNamePtrsMap->getValue(pName);
+        assert(ppElement != NULL);
+
+        if (ppElement != NULL)
+            return *ppElement;
+        else
+            return NULL;
+    }
+    else
+        return NULL;
+}
+
+void CSchemaMapManager::setElementWithName(const char* pName, CElement *pElement)
+{
+    assert (pName != NULL && *pName != 0 && pElement != NULL);
+
+    if (pName != NULL && *pName != 0 && pElement != NULL)
+    {
+        assert (pElement != NULL);
+        if (pName == NULL || *pName == 0 || pElement == NULL)
+            return;
+        if (m_pElementNamePtrsMap->getValue(pName) != NULL)
+        {
+            if (STRICTNESS_LEVEL >= DEFAULT_STRICTNESS)
+                assert(!"Redefintion");
+            else
+                PROGLOG("Symbol redefinition.  Possible misprocessing xsd file. Ignoring..");
+        }
+        assert(m_pElementNamePtrsMap->getLinkCount() == 1);
+        m_pElementNamePtrsMap->setValue(pName, pElement);
+    }
+}
+
+void CSchemaMapManager::addMapOfXPathToAttribute(const char*pXPath, CAttribute *pAttribute)
+{
+    assert (pAttribute != NULL);
+    assert(pXPath != NULL && *pXPath != 0);
+
+    // TODO:: throw exception if problems here
+    CAttribute **ppAttribute = m_pAttributePtrsMap->getValue(pXPath);
+
+    if (ppAttribute != NULL && *ppAttribute != pAttribute)
+        assert(!"Assigning different node with same xpath! delete it first!");
+
+    // should I remove automatically?
+    assert(pAttribute->getLinkCount() == 1);
+
+    StringBuffer strXPath(pXPath);
+    strXPath.replace('/','_');
+    m_pAttributePtrsMap->setValue(pXPath, pAttribute);
+    m_pAttributePtrsMap->setValue(strXPath.str(), pAttribute);
+}
+
+void CSchemaMapManager::removeMapOfXPathToAttribute(const char*pXPath)
+{
+    assert (m_pAttributePtrsMap->find(pXPath) != NULL);
+
+    StringBuffer strXPath(pXPath);
+    strXPath.replace('/','_');
+
+    m_pAttributePtrsMap->remove(pXPath);
+    m_pAttributePtrsMap->remove(strXPath.str());
+}
+
+CAttribute* CSchemaMapManager::getAttributeFromXPath(const char* pXPath)
+{
+    assert(pXPath != NULL && *pXPath != 0);
+    CAttribute **pAttribute = m_pAttributePtrsMap->getValue(pXPath);
+
+    if (pAttribute == NULL)
+    {
+        StringBuffer strXPath(pXPath);
+        strXPath.replace('/','_');
+        pAttribute = m_pAttributePtrsMap->getValue(pXPath);
+    }
+
+    if (STRICTNESS_LEVEL >= DEFAULT_STRICTNESS)
+        assert(pAttribute != NULL);
+    if (pAttribute == NULL)
+        return NULL;
+
+    return *pAttribute;
+}
+
+void CSchemaMapManager::addMapOfXSDXPathToElementArray(const char*pXPath, CElementArray *pElementArray)
+{
+    assert (pElementArray != NULL);
+    assert(pXPath != NULL && *pXPath != 0);
+    assert(pElementArray->getLinkCount() == 1);
+
+    if (m_pElementArrayPtrsMap->find(pXPath) != NULL)
+        return;  // already mapped, we must be dealing with live data
+
+    PROGLOG("Mapping XSD XPath %s to %p elementarray", pXPath, pElementArray);
+    m_pElementArrayPtrsMap->setValue(pXPath, pElementArray);
+}
+
+void CSchemaMapManager::removeMapOfXSDXPathToElementArray(const char*pXPath)
+{
+    assert (m_pElementArrayPtrsMap->find(pXPath) != NULL);
+    m_pElementArrayPtrsMap->remove(pXPath);
+}
+
+CElementArray* CSchemaMapManager::getElementArrayFromXSDXPath(const char* pXPath)
+{
+    assert(pXPath != NULL && *pXPath != 0);
+    if (pXPath == NULL)
+        return NULL;
+
+    CElementArray** ppElementArray = m_pElementArrayPtrsMap->getValue(pXPath);
+    if (ppElementArray != NULL)
+        return *ppElementArray;
+    else
+        return NULL;
+}
+
+void CSchemaMapManager::addMapOfXPathToElement(const char* pXPath, CElement *pElement,  bool bIsTopLevelElement)
+{
+    assert (pElement != NULL);
+    assert(pXPath != NULL && *pXPath != 0);
+    PROGLOG("Mapping XPath %s to %p element", pXPath, pElement);
+    assert(pElement->getLinkCount() == 1);
+
+    assert(m_pElementPtrsMap->getValue(pXPath) == NULL);
+    m_pElementPtrsMap->setValue(pXPath, pElement);
+}
+
+void CSchemaMapManager::removeMapOfXPathToElement(const char*pXPath)
+{
+    assert (m_pElementPtrsMap->find(pXPath) != NULL);
+    m_pElementPtrsMap->remove(pXPath);
+}
+
+CElement* CSchemaMapManager::getElementFromXPath(const char *pXPath)
+{
+    assert(pXPath != NULL && *pXPath != 0);
+    CElement **ppElement = m_pElementPtrsMap->getValue(pXPath);
+
+    assert(ppElement != NULL);
+    if (ppElement != NULL)
+        return *ppElement;
+    else
+        return NULL;
+}
+
+void CSchemaMapManager::addMapOfXSDXPathToElement(const char* pXPath, CElement *pElement)
+{
+    assert (pElement != NULL);
+    assert(pXPath != NULL && *pXPath != 0);
+
+    if (pElement != NULL && pXPath != NULL && *pXPath != 0)
+    {
+        StringBuffer strFullXPath;
+        strFullXPath.appendf("%s-%s",pElement->getConstSchemaNode()->getXSDXPath(), pXPath);
+        m_pXSDToElementPtrsMap->setValue(strFullXPath.str(), pElement);
+    }
+}
+
+void CSchemaMapManager::addMapOfXPathToElementArray(const char* pXPath, CElementArray *pElementArray)
+{
+    assert(pXPath != NULL && *pXPath != 0);
+    assert(pElementArray);
+
+    PROGLOG("Mapping Env XML XPath %s to %p elementarray", pXPath, pElementArray);
+
+    if (pElementArray != NULL && pXPath != NULL && *pXPath != 0)
+    {
+        StringBuffer strXPath(pXPath);
+        stripTrailingIndex(strXPath);
+
+        this->m_pElementArrayPtrsMap->setValue(strXPath.str(), pElementArray);
+    }
+}
+
+void CSchemaMapManager::removeMapOfXPathToElementArray(const char* pXPath)
+{
+    assert(pXPath != NULL && *pXPath != 0);
+    assert(m_pElementArrayPtrsMap->find(pXPath) != NULL);
+
+    this-m_pElementArrayPtrsMap->remove(pXPath);
+}
+
+CElementArray* CSchemaMapManager::getElementArrayFromXPath(const char *pXPath)
+{
+    assert(pXPath != NULL && *pXPath != 0);
+    assert(m_pElementArrayPtrsMap->getValue(pXPath) != NULL);
+
+    return *(this->m_pElementArrayPtrsMap->getValue(pXPath));
+}
+
+CElement* CSchemaMapManager::getElementFromXSDXPath(const char *pXPath) const
+{
+    UNIMPLEMENTED;
+    //return NULL;
+}
+
+void CSchemaMapManager::addMapOfXSDXPathToKey(const char* pXPath, CKey *pKey)
+{
+    assert (pKey != NULL);
+    assert (pXPath != NULL && *pXPath != 0);
+
+    if (pKey != NULL && pXPath != NULL && *pXPath != 0)
+        m_pStringToKeyPtrsMap->setValue(pXPath, pKey);
+}
+
+CKey* CSchemaMapManager::getKeyFromXSDXPath(const char *pXPath) const
+{
+    assert(pXPath != NULL && *pXPath != 0);
+    if (pXPath != NULL && *pXPath != 0)
+    {
+        CKey **ppKey = m_pStringToKeyPtrsMap->getValue(pXPath);
+        assert(ppKey != NULL);
+
+        if (ppKey != NULL)
+            return *ppKey;
+        else
+            return NULL;
+    }
+    assert(!"Control should reach here.  xpath invalid?");
+    return NULL;
+}
+
+void CSchemaMapManager::addMapOfXPathToRestriction(const char*pXPath, CRestriction *pRestriction)
+{
+    assert (pRestriction != NULL);
+    assert(pXPath != NULL && *pXPath != 0);
+    assert(m_pRestrictionPtrsMap->find(pXPath) == NULL);
+    assert(pRestriction->getLinkCount() == 1);
+
+    m_pRestrictionPtrsMap->setValue(pXPath, pRestriction);
+}
+
+void CSchemaMapManager::removeMapOfXPathToRestriction(const char*pXPath)
+{
+    assert(pXPath != NULL && *pXPath != 0);
+    m_pRestrictionPtrsMap->remove(pXPath);
+}
+
+CRestriction* CSchemaMapManager::getRestrictionFromXPath(const char* pXPath)
+{
+    assert(pXPath != NULL && *pXPath != 0);
+
+    CRestriction **ppRestriction = m_pRestrictionPtrsMap->getValue(pXPath);
+    assert(ppRestriction != NULL);
+
+    if (ppRestriction != NULL)
+        return *ppRestriction;
+    else
+        return NULL;
+}
+
+int CSchemaMapManager::getNumberOfComponents() const
+{
+    int nCount = 0;
+    HashIterator iter(*(m_pElementPtrsMap.get()));
+
+    ForEach(iter)
+    {
+        CElement *pElement = *(m_pElementPtrsMap->mapToValue(&iter.query()));
+        if (pElement->isTopLevelElement() == true)
+            nCount++;
+    }
+    return nCount;
+}
+
+CElement* CSchemaMapManager::getComponent(int index)
+{
+    assert(index >= 0 && index < getNumberOfComponents());
+    HashIterator iter(*(m_pElementPtrsMap.get()));
+
+    int nCount = 0;
+
+    ForEach(iter)
+    {
+        CElement *pElement = *(m_pElementPtrsMap->mapToValue(&iter.query()));
+        if (pElement->isTopLevelElement() == true)
+        {
+            if (nCount == index)
+                return pElement;
+            nCount++;
+        }        
+    }
+    return NULL;
+}
+
+int CSchemaMapManager::getIndexOfElement(const CElement *pElem)
+{
+    int nCount = 0;
+    HashIterator iter(*(m_pElementPtrsMap.get()));
+
+    ForEach(iter)
+    {
+        CElement *pElement = *(m_pElementPtrsMap->mapToValue(&iter.query()));
+
+        if (pElement == pElem)
+            return nCount;
+        if (pElement->isTopLevelElement() == true)
+            nCount++;
+    }
+    assert(false);
+    return -1;
+}
+
+enum NODE_TYPES CSchemaMapManager::getEnumFromTypeName(const char *pTypeName) const
+{
+    if (pTypeName == NULL || *pTypeName == 0)
+        return XSD_ERROR;
+
+    enum NODE_TYPES *eRet = (m_pStringToEnumMap->getValue(pTypeName));
+
+    if (eRet == NULL || *eRet == XSD_ERROR)
+    {
+        if (STRICTNESS_LEVEL >= MAXIMUM_STRICTNESS)
+            assert(!"Unknown XSD built in data type");
+
+        PROGLOG("Unknown XSD built in data type");
+        return XSD_ERROR;
+    }
+    return *eRet;
+}
+
+const char* CSchemaMapManager::getTypeNameFromEnum(enum NODE_TYPES eType, bool bForDump) const
+{
+    if (eType-XSD_DT_NORMALIZED_STRING > 0 && eType-XSD_DT_NORMALIZED_STRING < XSD_ERROR)
+        return m_enumArray[eType-XSD_DT_NORMALIZED_STRING][bForDump ? 1 : 0];
+
+    assert(!"Unknown XSD built-in type");
+    PROGLOG("Unknown XSD built-in type");
+    return NULL;
+}
+
+
+bool CSchemaMapManager::isNodeExcluded(enum NODE_TYPES nodeType) const
+{
+    auto result = m_setOfExludedNodeTypes.find(nodeType);
+
+    if (result == m_setOfExludedNodeTypes.end())
+        return true;
+
+    return false;
+}
+
+void CSchemaMapManager::addExludedNode(enum NODE_TYPES nodeType)
+{
+    m_setOfExludedNodeTypes.insert(nodeType);
+}

+ 152 - 0
configuration/configurator/SchemaMapManager.hpp

@@ -0,0 +1,152 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jhash.hpp"
+#include "jhash.ipp"
+#include "jlog.hpp"
+#include "SchemaCommon.hpp"
+#include <set>
+
+#ifndef _SCHEMA_MAP_MANAGER_HPP_
+#define _SCHEMA_MAP_MANAGER_HPP_
+
+namespace CONFIGURATOR
+{
+class CSchema;
+class CAttribute;
+class CAttributeGroup;
+class CSimpleType;
+class CComplexType;
+class CAttributeGroup;
+class CAttribute;
+class CRestriction;
+class CElementArray;
+class CElement;
+class CKey;
+
+class CSchemaMapManager
+{
+public:
+
+    CSchemaMapManager();
+    virtual ~CSchemaMapManager();
+
+    CSchema* getSchemaForXSD(const char* pComponent);
+    void setSchemaForXSD(const char* pComponent, CSchema *pSchema);
+
+    CSimpleType* getSimpleTypeWithName(const char* pName);
+    void setSimpleTypeWithName(const char* pName, CSimpleType *pSimpleType);
+
+    CComplexType* getComplexTypeWithName(const char* pName);
+    void setComplexTypeWithName(const char* pName, CComplexType *pComplexType);
+    CComplexType* getComplexTypeFromXPath(const char *pXPath);
+
+    CAttributeGroup *getAttributeGroup(const char* pName);
+    void setAttributeGroupTypeWithName(const char* pName, CAttributeGroup *pAttributeGroup);
+    CAttributeGroup* getAttributeGroupFromXPath(const char *pXPath);
+
+    CElement* getElementWithName(const char* pName);
+    void setElementWithName(const char* pName, CElement *pElement);
+
+    void addMapOfXPathToAttribute(const char* pXPath, CAttribute *pAttribute);
+    void removeMapOfXPathToAttribute(const char* pXPath);
+    CAttribute* getAttributeFromXPath(const char* pXPath);
+
+    void addMapOfXPathToRestriction(const char*pXPath, CRestriction *pRestriction);
+    void removeMapOfXPathToRestriction(const char*pXPath);
+    CRestriction* getRestrictionFromXPath(const char* pXPath);
+
+    void addMapOfXSDXPathToElementArray(const char* pXPath, CElementArray *pElementArray);
+    void removeMapOfXSDXPathToElementArray(const char* pXPath);
+    CElementArray* getElementArrayFromXSDXPath(const char* pXPath);
+
+    void addMapOfXPathToElement(const char* pXPath, CElement *pElement, bool bIsTopLevelElement = false);
+    void removeMapOfXPathToElement(const char* pXPath);
+    CElement* getElementFromXPath(const char *pXPath);
+
+    void addMapOfXPathToElementArray(const char* pXPath, CElementArray *pElementArray);
+    void removeMapOfXPathToElementArray(const char* pXPath);
+    CElementArray* getElementArrayFromXPath(const char *pXPath);
+
+    void addMapOfXSDXPathToElement(const char* pXPath, CElement *pElement);
+    CElement* getElementFromXSDXPath(const char *pXPath) const;
+
+    void addMapOfXSDXPathToKey(const char* pXPath, CKey *pKey);
+    CKey* getKeyFromXSDXPath(const char *pXPath) const;
+
+    int getNumberOfComponents() const;
+    CElement* getComponent(int index);
+    int getIndexOfElement(const CElement *pElem);
+
+    enum NODE_TYPES getEnumFromTypeName(const char *pTypeName) const;
+    const char* getTypeNameFromEnum(enum NODE_TYPES, bool bForDump = false) const;
+
+    bool isNodeExcluded(enum NODE_TYPES nodeType) const;
+    void addExludedNode(enum NODE_TYPES nodeType);
+
+protected:
+
+    typedef MapStringTo<CSchema*> MapStringToCSchema;
+    Owned<MapStringToCSchema> m_pSchemaPtrMap;
+
+    typedef MapStringTo<CSimpleType*> MapStringToCSimpleType;
+    Owned<MapStringToCSimpleType> m_pSimpleTypePtrMap;
+
+    typedef MapStringTo<CComplexType*> MapStringToCComplexType;
+    Owned<MapStringToCComplexType> m_pComplexTypePtrsMap;
+
+    typedef MapStringTo<CAttributeGroup*> MapStringToCAttributeGroup;
+    Owned<MapStringToCAttributeGroup> m_pAttributeGroupTypePtrsMap;
+
+    typedef MapStringTo<CAttribute*> MapStringToCAttribute;
+    Owned<MapStringToCAttribute> m_pAttributePtrsMap;
+
+    typedef MapStringTo<CRestriction*> MapStringToCRestriction;
+    Owned<MapStringToCRestriction> m_pRestrictionPtrsMap;
+
+    typedef MapStringTo<CElement*> MapStringToCElement;
+    Owned<MapStringToCElement> m_pElementPtrsMap;
+    Owned<MapStringToCElement> m_pElementNamePtrsMap;
+    Owned<MapStringToCElement> m_pXSDToElementPtrsMap;
+
+    typedef MapStringTo<CElementArray*> MapStringToCElementArray;
+    Owned<MapStringToCElementArray> m_pElementArrayPtrsMap;
+
+    const char* m_enumArray[XSD_ERROR][2];
+
+    typedef MapStringTo<enum NODE_TYPES> MapStringToNodeTypeEnum;
+    Owned<MapStringToNodeTypeEnum> m_pStringToEnumMap;
+
+    typedef MapStringTo<CKey*> MapStringToCKey;
+    Owned<MapStringToCKey> m_pStringToKeyPtrsMap;
+
+    typedef MapStringTo<CXSDNodeBase*> MapStringToCNodeBase;
+    Owned<MapStringToCNodeBase> m_pStringToNodeBaseMap;
+
+    struct STypeStrings
+    {
+        const char *pXSDTypeString;
+        const char *pDumpTypeString;
+    };
+
+    std::set<enum NODE_TYPES> m_setOfExludedNodeTypes;
+
+private:
+};
+
+}
+#endif // _SCHEMA_MAP_MANAGER_HPP_

+ 30 - 0
configuration/configurator/SchemaMaxExclusive.cpp

@@ -0,0 +1,30 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaMaxExclusive.hpp"
+
+using namespace CONFIGURATOR;
+
+CMaxExclusive* CMaxExclusive::load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    CMaxExclusive *pMaxExclusive = CXSDNodeWithRestrictions<CMaxExclusive>::load(pParentNode, pSchemaRoot, xpath);
+    if (pMaxExclusive == NULL)
+        return NULL;
+
+    pMaxExclusive->setMaxExclusive(pMaxExclusive->getValue());
+    return pMaxExclusive;
+}

+ 46 - 0
configuration/configurator/SchemaMaxExclusive.hpp

@@ -0,0 +1,46 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_MAX_EXCLUSIVE_HPP_
+#define _SCHEMA_MAX_EXCLUSIVE_HPP_
+
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CMaxExclusive : public CXSDNodeWithRestrictions<CMaxExclusive>
+{
+    friend class CXSDNodeWithRestrictions<CMaxExclusive>;
+public:
+
+    virtual ~CMaxExclusive()
+    {
+    }
+    static CMaxExclusive* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+protected:
+
+    CMaxExclusive(CXSDNodeBase* pParentNode = NULL) : CXSDNodeWithRestrictions<CMaxExclusive>::CXSDNodeWithRestrictions(pParentNode, XSD_MAX_EXCLUSIVE), m_nMaxExclusive(-1)
+    {
+    }
+    GETTERSETTER(Value)
+    GETTERSETTERINT(MaxExclusive)
+};
+
+}
+#endif // _SCHEMA_MAX_EXCLUSIVE_HPP_

+ 30 - 0
configuration/configurator/SchemaMaxInclusive.cpp

@@ -0,0 +1,30 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaMaxInclusive.hpp"
+
+using namespace CONFIGURATOR;
+
+CMaxInclusive* CMaxInclusive::load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    CMaxInclusive *pMaxInclusive = CXSDNodeWithRestrictions<CMaxInclusive>::load(pParentNode, pSchemaRoot, xpath);
+    if (pMaxInclusive == NULL)
+        return NULL;
+
+    pMaxInclusive->setMaxInclusive(pMaxInclusive->getValue());
+    return pMaxInclusive;
+}

+ 46 - 0
configuration/configurator/SchemaMaxInclusive.hpp

@@ -0,0 +1,46 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_MAX_INCLUSIVE_HPP_
+#define _SCHEMA_MAX_INCLUSIVE_HPP_
+
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CMaxInclusive : public CXSDNodeWithRestrictions<CMaxInclusive>
+{
+    friend class CXSDNodeWithRestrictions<CMaxInclusive>;
+public:
+
+    virtual ~CMaxInclusive()
+    {
+    }
+
+    static CMaxInclusive* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+    GETTERSETTERINT(MaxInclusive)
+
+protected:
+
+    CMaxInclusive(CXSDNodeBase* pParentNode = NULL) : CXSDNodeWithRestrictions<CMaxInclusive>::CXSDNodeWithRestrictions(pParentNode, XSD_MAX_INCLUSIVE), m_nMaxInclusive(-1)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_MAX_INCLUSIVE_HPP_

+ 30 - 0
configuration/configurator/SchemaMaxLength.cpp

@@ -0,0 +1,30 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaMaxLength.hpp"
+
+using namespace CONFIGURATOR;
+
+CMaxLength* CMaxLength::load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    CMaxLength *pMaxLength = CXSDNodeWithRestrictions<CMaxLength>::load(pParentNode, pSchemaRoot, xpath);
+    if (pMaxLength == NULL)
+        return NULL;
+
+    pMaxLength->setMaxLength(pMaxLength->getValue());
+    return pMaxLength;
+}

+ 46 - 0
configuration/configurator/SchemaMaxLength.hpp

@@ -0,0 +1,46 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_MAX_LENGTH_HPP_
+#define _SCHEMA_MAX_LENGTH_HPP_
+
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CMaxLength : public CXSDNodeWithRestrictions<CMaxLength>
+{
+    friend class CXSDNodeWithRestrictions<CMaxLength>;
+public:
+
+    virtual ~CMaxLength()
+    {
+    }
+    static CMaxLength* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+    GETTERSETTERINT(MaxLength)
+
+protected:
+
+    CMaxLength(CXSDNodeBase* pParentNode = NULL) : CXSDNodeWithRestrictions<CMaxLength>::CXSDNodeWithRestrictions(pParentNode, XSD_MAX_LENGTH), m_nMaxLength(-1)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_MAX_LENGTH_HPP_

+ 31 - 0
configuration/configurator/SchemaMinExclusive.cpp

@@ -0,0 +1,31 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaMinExclusive.hpp"
+
+using namespace CONFIGURATOR;
+
+CMinExclusive* CMinExclusive::load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    CMinExclusive *pMinExclusive = CXSDNodeWithRestrictions<CMinExclusive>::load(pParentNode, pSchemaRoot, xpath);
+
+    if (pMinExclusive == NULL)
+        return NULL;
+
+    pMinExclusive->setMinExclusive(pMinExclusive->getValue());
+    return pMinExclusive;
+}

+ 45 - 0
configuration/configurator/SchemaMinExclusive.hpp

@@ -0,0 +1,45 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_MIN_EXCLUSIVE_HPP_
+#define _SCHEMA_MIN_EXCLUSIVE_HPP_
+
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CMinExclusive : public CXSDNodeWithRestrictions<CMinExclusive>
+{
+    friend class CXSDNodeWithRestrictions<CMinExclusive>;
+public:
+
+    virtual ~CMinExclusive()
+    {
+    }
+    static CMinExclusive* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+    GETTERSETTERINT(MinExclusive)
+
+protected:
+
+    CMinExclusive(CXSDNodeBase* pParentNode = NULL) : CXSDNodeWithRestrictions<CMinExclusive>::CXSDNodeWithRestrictions<CMinExclusive>(pParentNode, XSD_MIN_EXCLUSIVE), m_nMinExclusive(-1)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_MIN_EXCLUSIVE_HPP_

+ 30 - 0
configuration/configurator/SchemaMinInclusive.cpp

@@ -0,0 +1,30 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaMinInclusive.hpp"
+
+using namespace CONFIGURATOR;
+
+CMinInclusive* CMinInclusive::load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    CMinInclusive *pMinInclusive = CXSDNodeWithRestrictions<CMinInclusive>::load(pParentNode, pSchemaRoot, xpath);
+    if (pMinInclusive == NULL)
+        return NULL;
+
+    pMinInclusive->setMinInclusive(pMinInclusive->getValue());
+    return pMinInclusive; 
+}

+ 46 - 0
configuration/configurator/SchemaMinInclusive.hpp

@@ -0,0 +1,46 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_MIN_INCLUSIVE_HPP_
+#define _SCHEMA_MIN_INCLUSIVE_HPP_
+
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CMinInclusive : public CXSDNodeWithRestrictions<CMinInclusive>
+{
+    friend class CXSDNodeWithRestrictions<CMinInclusive>;
+public:
+
+    virtual ~CMinInclusive()
+    {
+    }
+    static CMinInclusive* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+    GETTERSETTERINT(MinInclusive)
+
+protected:
+
+    CMinInclusive(CXSDNodeBase* pParentNode = NULL) : CXSDNodeWithRestrictions<CMinInclusive>::CXSDNodeWithRestrictions(pParentNode, XSD_MIN_INCLUSIVE), m_nMinInclusive(-1)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_MIN_INCLUSIVE_HPP_

+ 30 - 0
configuration/configurator/SchemaMinLength.cpp

@@ -0,0 +1,30 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaMinLength.hpp"
+
+using namespace CONFIGURATOR;
+
+CMinLength* CMinLength::load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    CMinLength *pMinLength = CXSDNodeWithRestrictions<CMinLength>::load(pParentNode, pSchemaRoot, xpath);
+    if (pMinLength == NULL)
+        return NULL;
+
+    pMinLength->setMinLength(pMinLength->getValue());
+    return pMinLength;
+}

+ 45 - 0
configuration/configurator/SchemaMinLength.hpp

@@ -0,0 +1,45 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_MIN_LENGTH_HPP_
+#define _SCHEMA_MIN_LENGTH_HPP_
+
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+class CMinLength : public CXSDNodeWithRestrictions<CMinLength>
+{
+    friend class CXSDNodeWithRestrictions<CMinLength>;
+public:
+
+    virtual ~CMinLength()
+    {
+    }
+    static CMinLength* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+    GETTERSETTERINT(MinLength)
+
+protected:
+
+    CMinLength(CXSDNodeBase* pParentNode = NULL) : CXSDNodeWithRestrictions<CMinLength>::CXSDNodeWithRestrictions(pParentNode, XSD_MIN_LENGTH), m_nMinLength(-1)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_MIN_LENGTH_HPP_

+ 30 - 0
configuration/configurator/SchemaPattern.cpp

@@ -0,0 +1,30 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaPattern.hpp"
+
+using namespace CONFIGURATOR;
+
+CPattern* CPattern::load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    CPattern *pPattern = CXSDNodeWithRestrictions<CPattern>::load(pParentNode, pSchemaRoot, xpath);
+    if (pPattern == NULL)
+        return NULL;
+
+    pPattern->setPattern(pPattern->getValue());
+    return pPattern;
+}

+ 46 - 0
configuration/configurator/SchemaPattern.hpp

@@ -0,0 +1,46 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_PATTERN_HPP_
+#define _SCHEMA_PATTERN_HPP_
+
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CPattern : public CXSDNodeWithRestrictions<CPattern>
+{
+    friend class CXSDNodeWithRestrictions<CPattern>;
+public:
+
+    virtual ~CPattern()
+    {
+    }
+    static CPattern* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+    GETTERSETTER(Pattern)
+
+private:
+
+    CPattern(CXSDNodeBase* pParentNode = NULL) : CXSDNodeWithRestrictions<CPattern>::CXSDNodeWithRestrictions(pParentNode, XSD_PATTERN)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_PATTERN_HPP_

+ 176 - 0
configuration/configurator/SchemaRestriction.cpp

@@ -0,0 +1,176 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jptree.hpp"
+#include "SchemaRestriction.hpp"
+#include "SchemaEnumeration.hpp"
+#include "SchemaAttributes.hpp"
+#include "XMLTags.h"
+#include "ConfigSchemaHelper.hpp"
+#include "DocumentationMarkup.hpp"
+#include "SchemaMapManager.hpp"
+#include "SchemaFractionDigits.hpp"
+#include "SchemaLength.hpp"
+#include "SchemaTotalDigits.hpp"
+#include "SchemaWhiteSpace.hpp"
+#include "SchemaSimpleContent.hpp"
+
+using namespace CONFIGURATOR;
+
+#define StringBuffer ::StringBuffer
+#define IPropertyTree ::IPropertyTree
+
+#define QUICK_LOAD_XSD_RESTRICTIONS(X, Y)       \
+    strXPathExt.set(xpath);                     \
+    strXPathExt.append("/").append(Y);          \
+    C##X *p##X = C##X::load(pRestriction, pSchemaRoot, strXPathExt.str());    \
+    if (p##X != NULL) pRestriction->set##X(p##X);
+
+CRestriction::~CRestriction()
+{
+    CConfigSchemaHelper::getInstance()->getSchemaMapManager()->removeMapOfXPathToRestriction(this->getEnvXPath());
+}
+
+void CRestriction::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_RESTRICTION_STR, offset);
+    QUICK_OUT_2(Base);
+    QUICK_OUT_2(ID);
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QUICK_OUT(cout, EnvXPath,  offset);
+    QUICK_OUT(cout, EnvValueFromXML,  offset);
+    QUICK_OUT_3(EnumerationArray)
+    QUICK_OUT_3(FractionDigits)
+    QUICK_OUT_3(Length)
+    QUICK_OUT_3(MaxExclusive)
+    QUICK_OUT_3(MaxInclusive)
+    QUICK_OUT_3(MinExclusive)
+    QUICK_OUT_3(MinInclusive)
+    QUICK_OUT_3(MaxLength)
+    QUICK_OUT_3(MinLength)
+    QUICK_OUT_3(Pattern)
+    QUICK_OUT_3(TotalDigits)
+    QUICK_OUT_3(WhiteSpace)
+    QuickOutFooter(cout, XSD_RESTRICTION_STR, offset);
+}
+
+void CRestriction::getDocumentation(StringBuffer &strDoc) const
+{
+    if (m_pEnumerationArray != NULL)
+    {
+        strDoc.appendf("<%s>",DM_PARA);
+        DEBUG_MARK_STRDOC
+        m_pEnumerationArray->getDocumentation(strDoc);
+        strDoc.appendf("</%s>",DM_PARA);
+        DEBUG_MARK_STRDOC
+    }
+}
+
+void CRestriction::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    this->setEnvXPath(strXPath);
+    CConfigSchemaHelper::getInstance()->getSchemaMapManager()->addMapOfXPathToRestriction(this->getEnvXPath(), this);
+
+    if (this->m_pEnumerationArray != NULL)
+        this->m_pEnumerationArray->populateEnvXPath(strXPath);
+}
+
+void CRestriction::loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+{
+    if (m_pEnumerationArray != NULL)
+        m_pEnumerationArray->loadXMLFromEnvXml(pEnvTree);
+}
+
+CRestriction* CRestriction::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    if (pParentNode == NULL || pSchemaRoot == NULL)
+        return NULL;
+
+    IPropertyTree *pTree = pSchemaRoot->queryPropTree(xpath);
+    const char* pID =  NULL;
+    const char* pBase =  NULL;
+
+    pID = pTree->queryProp(XML_ATTR_ID);
+    pBase = pTree->queryProp(XML_ATTR_BASE);
+
+    CRestriction* pRestriction = new CRestriction(pParentNode, pID, pBase);
+    pRestriction->setXSDXPath(xpath);
+
+    StringBuffer strXPathExt;
+    QUICK_LOAD_XSD_RESTRICTIONS(EnumerationArray, XSD_TAG_ENUMERATION)
+    QUICK_LOAD_XSD_RESTRICTIONS(FractionDigits, XSD_TAG_FRACTION_DIGITS)
+    QUICK_LOAD_XSD_RESTRICTIONS(Length, XSD_TAG_LENGTH)
+    QUICK_LOAD_XSD_RESTRICTIONS(MaxExclusive, XSD_TAG_MAX_EXCLUSIVE)
+    QUICK_LOAD_XSD_RESTRICTIONS(MaxInclusive, XSD_TAG_MAX_INCLUSIVE)
+    QUICK_LOAD_XSD_RESTRICTIONS(MinExclusive, XSD_TAG_MIN_EXCLUSIVE)
+    QUICK_LOAD_XSD_RESTRICTIONS(MinInclusive, XSD_TAG_MIN_INCLUSIVE)
+    QUICK_LOAD_XSD_RESTRICTIONS(MaxLength, XSD_TAG_MAX_LENGTH)
+    QUICK_LOAD_XSD_RESTRICTIONS(MinLength, XSD_TAG_MIN_LENGTH)
+    QUICK_LOAD_XSD_RESTRICTIONS(Pattern, XSD_TAG_PATTERN)
+    QUICK_LOAD_XSD_RESTRICTIONS(TotalDigits, XSD_TAG_TOTAL_DIGITS)
+    QUICK_LOAD_XSD_RESTRICTIONS(WhiteSpace, XSD_TAG_WHITE_SPACE)
+
+    if (pBase != NULL && *pBase != 0 && pRestriction != NULL)
+        CConfigSchemaHelper::getInstance()->addNodeForBaseProcessing(pRestriction);
+
+    return pRestriction;
+}
+
+const char* CRestriction::getXML(const char* /*pComponent*/)
+{
+    if (m_strXML.length () == 0)
+    {
+        m_strXML.append("<").append(getBase()).append("\n");
+        m_strXML.append("<").append(getID()).append("\n");
+        m_strXML.append("/>\n");
+    }
+    return m_strXML.str();
+}
+
+bool CRestriction::checkConstraint(const char *pValue) const
+{
+    const CXSDNodeBase *pNodeBase = this->getBaseNode();
+    assert(pNodeBase != NULL);
+
+    if (pNodeBase != NULL)
+    {
+        const CXSDBuiltInDataType *pNodeBuiltInType = dynamic_cast<const CXSDBuiltInDataType*>(pNodeBase);
+
+        if (pNodeBuiltInType != NULL && pNodeBuiltInType->checkConstraint(pValue) == false)
+            return false;
+
+        if (pNodeBase->getNodeType() == XSD_SIMPLE_TYPE)
+        {
+            const CSimpleType *pNodeSimpleType = dynamic_cast<const CSimpleType*>(pNodeBase);
+
+            if (pNodeSimpleType != NULL && pNodeSimpleType->checkConstraint(pValue) == false)
+               return false;
+        }
+        else if (pNodeBase->getNodeType() == XSD_SIMPLE_CONTENT)
+        {
+            const CSimpleContent *pNodeSimpleContent = dynamic_cast<const CSimpleContent*>(pNodeBase);
+
+            if (pNodeSimpleContent != NULL && pNodeSimpleContent->checkConstraint(pValue) == false)
+                return false;
+        }
+         assert(!"Unknown base node in restriction");
+         return false;
+    }
+    return true;
+}

+ 88 - 0
configuration/configurator/SchemaRestriction.hpp

@@ -0,0 +1,88 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_RESTRICTION_HPP_
+#define _SCHEMA_RESTRICTION_HPP_
+
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CEnumerationArray;
+class CFractionDigits;
+class CLength;
+class CMaxExclusive;
+class CMaxInclusive;
+class CMinExclusive;
+class CMinInclusive;
+class CMaxLength;
+class CMinLength;
+class CPattern;
+class CTotalDigits;
+class CWhiteSpace;
+
+class CRestriction : public CXSDNodeWithBase
+{
+public:
+
+    virtual ~CRestriction();
+
+    GETTERSETTER(ID)
+
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const;
+    virtual const char* getXML(const char* /*pComponent*/);
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+    bool checkConstraint(const char *pValue) const;
+
+    static CRestriction* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+protected:
+
+    CRestriction(CXSDNodeBase* pParentNode = NULL, const char* pID = NULL, const char* pBase = NULL) : CXSDNodeWithBase::CXSDNodeWithBase(pParentNode, XSD_RESTRICTION), m_strID(pID), m_pEnumerationArray(NULL)
+    {
+    }
+    GETTERSETTERTYPE(EnumerationArray)
+    GETTERSETTERTYPE(FractionDigits)
+    GETTERSETTERTYPE(Length)
+    GETTERSETTERTYPE(MaxExclusive)
+    GETTERSETTERTYPE(MaxInclusive)
+    GETTERSETTERTYPE(MinExclusive)
+    GETTERSETTERTYPE(MinInclusive)
+    GETTERSETTERTYPE(MaxLength)
+    GETTERSETTERTYPE(MinLength)
+    GETTERSETTERTYPE(Pattern)
+    GETTERSETTERTYPE(TotalDigits)
+    GETTERSETTERTYPE(WhiteSpace)
+
+protected:
+
+    CXSDNodeBase *m_pXSDNode;
+
+private:
+
+    CRestriction(CXSDNodeBase* pParentNode = NULL) : CXSDNodeWithBase::CXSDNodeWithBase(pParentNode, XSD_RESTRICTION), m_pEnumerationArray(NULL), m_pFractionDigits(NULL), m_pLength(NULL),
+        m_pMaxExclusive(NULL), m_pMaxInclusive(NULL), m_pMinExclusive(NULL), m_pMinInclusive(NULL), m_pMaxLength(NULL), m_pMinLength(NULL),
+        m_pPattern(NULL), m_pTotalDigits(NULL), m_pWhiteSpace(NULL), m_pXSDNode(NULL)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_RESTRICTION_HPP_

+ 364 - 0
configuration/configurator/SchemaSchema.cpp

@@ -0,0 +1,364 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jptree.hpp"
+#include "XMLTags.h"
+
+#include "SchemaSchema.hpp"
+#include "ConfigSchemaHelper.hpp"
+#include "DocumentationMarkup.hpp"
+#include "SchemaMapManager.hpp"
+#include "JSONMarkUp.hpp"
+
+using namespace CONFIGURATOR;
+
+#define StringBuffer ::StringBuffer
+#define IPropertyTree ::IPropertyTree
+
+CSchema::~CSchema()
+{
+    assert(this->getLinkCount() == 1);
+}
+
+CSchema* CSchema::load(const char* pSchemaLocation, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    if (pSchemaRoot == NULL)
+        return NULL;
+
+    CConfigSchemaHelper *pSchemaHelper = (CConfigSchemaHelper::getInstance());
+    if (pSchemaHelper->getSchemaMapManager()->getSchemaForXSD(pSchemaLocation) != NULL)  // check to see if the this schema has already been processed
+        return pSchemaHelper->getSchemaMapManager()->getSchemaForXSD(pSchemaLocation);
+
+
+    CSchema* pSchema = new CSchema(pSchemaLocation);
+    pSchema->setXSDXPath(xpath);
+
+    IPropertyTree *pTree = pSchemaRoot->queryPropTree(xpath);
+    if (pTree == NULL)
+        return NULL;
+
+    pSchema->setXMLNS_XS(pTree->queryProp(XML_ATTR_XMLNS_XS));
+    pSchema->setElementFormDefault(pTree->queryProp(XML_ATTR_ELEMENTFORMDEFAULT));
+    pSchema->setAttributeFormDefault(pTree->queryProp(XML_ATTR_ATTRIBUTEFORMDEFAULT));
+
+    StringBuffer strXPathExt(xpath);
+    strXPathExt.clear().append(xpath).append(XSD_TAG_INCLUDE);
+
+    CIncludeArray* pIncludeArray = NULL;//CIncludeArray::load(pSchema, pSchemaRoot, strXPathExt); // change this back to be uncommented
+
+    strXPathExt.clear().append(xpath).append(XSD_TAG_SIMPLE_TYPE);
+
+    CSimpleTypeArray* pSimpleTypeArray = CSimpleTypeArray::load(pSchema, pSchemaRoot, strXPathExt);
+
+    strXPathExt.clear().append(xpath).append(XSD_TAG_COMPLEX_TYPE);
+    CComplexTypeArray* pComplexTypeArray = CComplexTypeArray::load(pSchema, pSchemaRoot, strXPathExt);
+
+    strXPathExt.clear().append(xpath).append(XSD_TAG_ELEMENT);
+    //CElementArray* pElemArray = CElementArray::load(pSchema, pSchemaRoot, strXPathExt.str());
+    CArrayOfElementArrays* pArrayOfElemArray = CArrayOfElementArrays::load(pSchema, pSchemaRoot, strXPathExt.str());
+
+    strXPathExt.clear().append(xpath).append(XSD_TAG_ATTRIBUTE_GROUP);
+    CAttributeGroupArray* pAttributeGroupArray = CAttributeGroupArray::load(pSchema, pSchemaRoot, strXPathExt);
+
+    strXPathExt.clear().append(xpath).append(XSD_TAG_ANNOTATION);
+    CAnnotation* pAnnotation = CAnnotation::load(pSchema, pSchemaRoot, strXPathExt);
+    pSchema->m_pAnnotation = pAnnotation;
+
+    pSchema->m_pArrayElementOfArrays = pArrayOfElemArray;
+    pSchema->m_pComplexTypeArray = pComplexTypeArray;
+
+    if (pSchema->m_pAttributeGroupArray == NULL)
+        pSchema->m_pAttributeGroupArray = pAttributeGroupArray;
+    else
+        // copy contents from from pAttributeGroupArray to pSchema->m_pAttributeGroupArray
+
+    pSchema->m_pSimpleTypeArray = pSimpleTypeArray;
+    pSchema->m_pIncludeArray = pIncludeArray;
+
+    pSchemaHelper->getSchemaMapManager()->setSchemaForXSD(pSchemaLocation, pSchema);
+
+    CConfigSchemaHelper::getInstance()->processAttributeGroupArr();
+    CConfigSchemaHelper::getInstance()->processExtensionArr();
+    CConfigSchemaHelper::getInstance()->processNodeWithTypeArr(pSchema);
+
+    return pSchema;
+}
+
+CSchema* CSchema::load(const char* pSchemaLocation, CXSDNodeBase* pParentNode)
+{
+    if (pSchemaLocation == NULL)
+        return NULL;
+
+    Linked<IPropertyTree> pSchemaRoot;
+    StringBuffer schemaPath;
+
+    if (CConfigSchemaHelper::getInstance()->getBasePath() == NULL)
+        schemaPath.appendf("%s%s", DEFAULT_SCHEMA_DIRECTORY, pSchemaLocation);
+    else
+        schemaPath.appendf("%s/%s", CConfigSchemaHelper::getInstance()->getBasePath(), pSchemaLocation);
+
+    try
+    {
+       pSchemaRoot.setown(createPTreeFromXMLFile(schemaPath.str()));
+    }
+    catch (...)
+    {
+        // TODO: Hanlde exceptions
+        ::std::cout << "Can't open " << schemaPath.str() << ::std::endl;
+        exit(-1);
+    }
+
+    CSchema *pSchema = CSchema::load(pSchemaLocation, pSchemaRoot, XSD_TAG_SCHEMA);
+    SETPARENTNODE(pSchema, pParentNode)
+
+    return pSchema;
+}
+
+void CSchema::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_SCHEMA_STR, offset);
+    QUICK_OUT_2(XMLNS_XS);
+    QUICK_OUT_2(ElementFormDefault);
+    QUICK_OUT_2(AttributeFormDefault);
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QUICK_OUT(cout, EnvXPath,  offset);
+
+    if (m_pArrayElementOfArrays != NULL)
+        m_pArrayElementOfArrays->dump(cout, offset);
+    if (m_pComplexTypeArray != NULL)
+        m_pComplexTypeArray->dump(cout, offset);
+    if (m_pSimpleTypeArray != NULL)
+        m_pSimpleTypeArray->dump(cout, offset);
+    if (m_pIncludeArray != NULL)
+        m_pIncludeArray->dump(cout, offset);
+    if (m_pAnnotation != NULL)
+        m_pAnnotation->dump(cout, offset);
+    if (m_pAttributeGroupArray != NULL)
+        m_pAttributeGroupArray->dump(cout, offset);
+
+    QuickOutFooter(cout, XSD_SCHEMA_STR, offset);
+}
+
+void CSchema::getDocumentation(StringBuffer &strDoc) const
+{
+    if (m_pArrayElementOfArrays != NULL)
+        m_pArrayElementOfArrays->getDocumentation(strDoc);
+    if (m_pComplexTypeArray != NULL)
+        m_pComplexTypeArray->getDocumentation(strDoc);
+    if (m_pAttributeGroupArray != NULL)
+        m_pAttributeGroupArray->getDocumentation(strDoc);
+    if (m_pSimpleTypeArray != NULL)
+        m_pSimpleTypeArray->getDocumentation(strDoc);
+    if (m_pIncludeArray != NULL)
+        m_pIncludeArray->getDocumentation(strDoc);
+
+    strDoc.append(DM_SECT2_END);
+}
+
+void CSchema::getJSON(StringBuffer &strJSON, unsigned int offset, int idx) const
+{
+    strJSON.append(JSON_BEGIN);
+    offset += STANDARD_OFFSET_1;
+    QuickOutPad(strJSON, offset);
+
+    //offset -= STANDARD_OFFSET_1;
+    if (m_pArrayElementOfArrays != NULL)
+    {
+        //strJSON.append("{");
+        m_pArrayElementOfArrays->item(0).getJSON(strJSON, offset, idx);
+        //strJSON.append("}");
+        //m_pArrayElementOfArrays->getJSON(strJSON, offset, idx);
+        //DEBUG_MARK_JSON;
+    }
+    if (m_pComplexTypeArray != NULL)
+    {
+        //m_pComplexTypeArray->getJSON(strJSON, offset);
+        //DEBUG_MARK_JSON;
+    }
+    //offset -= STANDARD_OFFSET_1;
+    strJSON.append(JSON_END);
+
+}
+
+void  CSchema::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    strXPath.append("./").append(XML_TAG_SOFTWARE);
+
+    if (m_pArrayElementOfArrays != NULL)
+    {
+        m_pArrayElementOfArrays->populateEnvXPath(strXPath);
+        //CConfigSchemaHelper::getInstance()->getSchemaMapManager()->addMapOfXSDXPathToElementArray(m_pArrayElementOfArrays->getXSDXPath(), m_pArrayElementOfArrays);
+    }
+    if (m_pAttributeGroupArray != NULL)
+        m_pAttributeGroupArray->populateEnvXPath(strXPath);
+    if (m_pSimpleTypeArray != NULL)
+        m_pSimpleTypeArray->populateEnvXPath(strXPath);
+    if (m_pIncludeArray != NULL)
+        m_pIncludeArray->populateEnvXPath(strXPath);
+    if (m_pComplexTypeArray != NULL)
+    {
+        assert(m_pComplexTypeArray != 0);
+        m_pComplexTypeArray->populateEnvXPath(strXPath);
+    }
+    this->setEnvXPath(strXPath);
+}
+
+void CSchema::loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+{
+    assert(pEnvTree != NULL);
+
+    if (m_pArrayElementOfArrays != NULL)
+        m_pArrayElementOfArrays->loadXMLFromEnvXml(pEnvTree);
+    if (m_pComplexTypeArray != NULL)
+        m_pComplexTypeArray->loadXMLFromEnvXml(pEnvTree);
+    if (m_pAttributeGroupArray != NULL)
+        m_pAttributeGroupArray->loadXMLFromEnvXml(pEnvTree);
+    if (m_pSimpleTypeArray != NULL)
+        m_pSimpleTypeArray->loadXMLFromEnvXml(pEnvTree);
+    if (m_pIncludeArray != NULL)
+        m_pIncludeArray->loadXMLFromEnvXml(pEnvTree);
+    if (m_pAttributeGroupArray != NULL)
+        m_pAttributeGroupArray->loadXMLFromEnvXml(pEnvTree);
+
+    CConfigSchemaHelper::getInstance()->processAttributeGroupArr();
+}
+
+const char* CSchema::getXML(const char* /*pComponent*/)
+{
+    if (m_strXML.length() == 0)
+    {
+        int length =  m_pArrayElementOfArrays->length();
+
+        if (m_pArrayElementOfArrays != NULL)
+        {
+            for (int idx = 0; idx < length; idx++)
+            {
+                CElementArray &ElementArray = m_pArrayElementOfArrays->item(idx);
+
+                for (int idx2 = 0; idx2 < ElementArray.ordinality(); idx2++)
+                {
+                    CElement &Element = ElementArray.item(idx2);
+
+                    m_strXML.append(Element.getXML(NULL));
+
+                    if (idx+2 < length)
+                        m_strXML.append("\n");
+                }
+            }
+        }
+        if (m_pAttributeGroupArray != NULL)
+        {
+            length = m_pAttributeGroupArray->length();
+            for (int idx = 0; idx < length; idx++)
+            {
+                CAttributeGroup &AttributeGroup  = m_pAttributeGroupArray->item(idx);
+                m_strXML.append(AttributeGroup.getXML(NULL));
+
+                if (idx+1 < length)
+                    m_strXML.append("\n");
+            }
+        }
+
+        m_strXML.append("/>\n");
+
+        if (m_pComplexTypeArray != NULL)
+        {
+            length = m_pComplexTypeArray->length();
+            for (int idx = 0; idx < length; idx++)
+            {
+                CComplexType &ComplexType = m_pComplexTypeArray->item(idx);
+                m_strXML.append(ComplexType.getXML(NULL));
+
+                if (idx+1 < length)
+                     m_strXML.append("\n");
+            }
+        }
+        if (m_pSimpleTypeArray != NULL)
+        {
+            length = m_pSimpleTypeArray->length();
+            for (int idx = 0; idx < length; idx++)
+            {
+                CSimpleType &SimpleType = m_pSimpleTypeArray->item(idx);
+
+                m_strXML.append(SimpleType.getXML(NULL));
+
+                if (idx+1 < length)
+                    m_strXML.append("\n");
+            }
+        }
+        if (m_pIncludeArray != NULL)
+        {
+            length = m_pIncludeArray->length();
+            for (int idx = 0; idx < length; idx++)
+            {
+                CInclude &Include = m_pIncludeArray->item(idx);
+                m_strXML.append(Include.getXML(NULL));
+
+                if (idx+1 < length)
+                    m_strXML.append("\n");
+            }
+        }
+    }
+    return m_strXML.str();
+}
+
+CXSDNode* CSchema::getExtensionType(const char* pExtensionTypeName) const
+{
+    if (pExtensionTypeName == NULL)
+        return NULL;
+
+    if (m_pSimpleTypeArray != NULL)
+    {
+        int length = m_pSimpleTypeArray->length();
+
+        for (int idx = 0; idx < length; idx++)
+        {
+            CSimpleType &SimpleType = m_pSimpleTypeArray->item(idx);
+
+            if (strcmp(SimpleType.getName(), pExtensionTypeName) == 0)
+                return &SimpleType;
+        }
+    }
+    if (m_pComplexTypeArray != NULL)
+    {
+        int length = m_pComplexTypeArray->length();
+
+        for (int idx = 0; idx < length; idx++)
+        {
+            CComplexType &ComplexType = m_pComplexTypeArray->item(idx);
+
+            if (strcmp(ComplexType.getName(), pExtensionTypeName) == 0)
+                return &ComplexType;
+        }
+    }
+    return NULL;
+}
+
+const char* CSchema::getSchemaFileName() const
+{
+    String tempString(m_strSchemaLocation.str());
+
+    int idx = tempString.lastIndexOf('\\');
+
+    if (idx == -1)
+        return m_strSchemaLocation.str();
+    else
+        return &((m_strSchemaLocation.str())[idx]);
+}

+ 91 - 0
configuration/configurator/SchemaSchema.hpp

@@ -0,0 +1,91 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_SCHEMA_HPP_
+#define _SCHEMA_SCHEMA_HPP_
+
+#include "jarray.hpp"
+#include "jstring.hpp"
+#include "SchemaAll.hpp"
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CSchema : public InterfaceImpl, public CXSDNodeBase
+{
+public:
+
+    virtual ~CSchema();
+
+    GETTERSETTER(XMLNS_XS)
+    GETTERSETTER(ElementFormDefault)
+    GETTERSETTER(AttributeFormDefault)
+
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(StringBuffer &strDoc) const;
+    virtual void getJSON(StringBuffer &strJSON, unsigned int offset = 0, int idx = -1) const;
+    virtual void populateEnvXPath(StringBuffer strXPath, unsigned int index = 1);
+    virtual const char* getXML(const char* /*pComponent*/);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+
+    CXSDNode* getExtensionType(const char* pExtensionTypeName) const;
+
+    const char* getSchemaLocation() const
+    {
+        return m_strSchemaLocation.str();
+    }
+
+    const char* getSchemaFileName() const;
+
+    CComplexTypeArray* getComplexTypeArray() const
+    {
+        return m_pComplexTypeArray;
+    }
+
+    virtual CAnnotation* getAnnotation() const
+    {
+        return m_pAnnotation;
+    }
+
+    static CSchema* load(const char* pSchemaLocation, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+    static CSchema* load(const char* pSchemaLocation, CXSDNodeBase* pParentNode);
+
+protected:
+
+    CSchema(const char * pSchemaLocation, const char* pXMLNS_XS = NULL, const char* pElementFormDefault = NULL, const char* pAttributeFormDefault = NULL,
+            CArrayOfElementArrays* pArrayOfElementArrays = NULL, CComplexTypeArray* pComplexTypeArray = NULL, CAttributeGroupArray* pAttributeGroupArray = NULL,
+            CSimpleTypeArray* pSimpleTypeArray = NULL, CIncludeArray* pIncludeArray = NULL, CAnnotation *pAnnotation = NULL) : CXSDNodeBase::CXSDNodeBase(NULL, XSD_SCHEMA), m_strSchemaLocation(pSchemaLocation),
+                m_strXMLNS_XS(pXMLNS_XS), m_strElementFormDefault(pElementFormDefault), m_strAttributeFormDefault(pAttributeFormDefault),
+                m_pArrayElementOfArrays(pArrayOfElementArrays), m_pComplexTypeArray(pComplexTypeArray), m_pAttributeGroupArray(pAttributeGroupArray),
+                m_pSimpleTypeArray(pSimpleTypeArray), m_pIncludeArray(pIncludeArray), m_pAnnotation(pAnnotation)
+    {
+    }
+
+    StringBuffer            m_strSchemaLocation;
+    CArrayOfElementArrays*  m_pArrayElementOfArrays;
+    CComplexTypeArray*      m_pComplexTypeArray;
+    CAttributeGroupArray*   m_pAttributeGroupArray;
+    CSimpleTypeArray*       m_pSimpleTypeArray;
+    CIncludeArray*          m_pIncludeArray;
+    CAnnotation*            m_pAnnotation;
+
+private:
+};
+
+}
+#endif // _SCHEMA_SCHEMA_HPP_

+ 94 - 0
configuration/configurator/SchemaSelector.cpp

@@ -0,0 +1,94 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaSelector.hpp"
+#include "SchemaCommon.hpp"
+
+using namespace CONFIGURATOR;
+
+#define IPropertyTree ::IPropertyTree
+#define StringBuffer ::StringBuffer
+
+CSelector* CSelector::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    assert(pParentNode != NULL);
+    assert(pParentNode->getNodeType() == XSD_KEY || pParentNode->getNodeType() == XSD_KEYREF || pParentNode->getNodeType() == XSD_UNIQUE);
+
+    if (pSchemaRoot == NULL || pParentNode == NULL)
+    {
+        // TODO: Throw Exception
+        assert(false);
+        return NULL;
+    }
+
+    CSelector *pSelector = NULL;
+
+    if (xpath != NULL && *xpath != 0)
+    {
+        IPropertyTree* pTree = pSchemaRoot->queryPropTree(xpath);
+
+        if (pTree == NULL)
+        {
+            assert(!"Selector required");
+            // TODO: throw MakeExceptionFromMap("EX_STR_MISSING_SELECTOR_MISSING");
+        }
+        const char* pXPath = pSchemaRoot->getPropTree(xpath)->queryProp(XML_ATTR_XPATH);
+        assert(pXPath != NULL && *pXPath != 0);
+
+        if (pXPath == NULL || *pXPath == 0)
+        {
+            assert(!"Throw Exception");
+            return NULL;
+             // TODO: throw exception
+        }
+        if (pXPath != NULL)
+        {
+            pSelector = new CSelector(pParentNode);
+            pSelector->setXSDXPath(xpath);
+            pSelector->setXPath(pXPath);
+        }
+        else
+        {
+            assert(!"selector can not be be empty!");
+            // TODO: throw MakeExceptionFromMap(EX_STR_MISSING_VALUE_ATTRIBUTE_IN_LENGTH);
+        }
+
+        const char *pID = pSchemaRoot->getPropTree(xpath)->queryProp(XML_ATTR_ID);
+        if (pID != NULL)
+         pSelector->setID(pID);
+    }
+    return pSelector;
+}
+
+void CSelector::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset += STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_SELECTOR_STR, offset);
+    QUICK_OUT(cout, XPath, offset);
+    QUICK_OUT(cout, ID, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QuickOutFooter(cout, XSD_SELECTOR_STR, offset);
+}
+
+void CSelector::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    this->setEnvXPath(&(strXPath.str()[1]));  // strip out .
+    PROGLOG("Function: %s() at %s:%d", __func__, __FILE__, __LINE__);
+    PROGLOG("Setting selector %s to EnvXPath = %s", this->getXSDXPath(), this->getEnvXPath());
+}

+ 56 - 0
configuration/configurator/SchemaSelector.hpp

@@ -0,0 +1,56 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_SELECTOR_HPP_
+#define _SCHEMA_SELECTOR_HPP_
+
+#include "SchemaCommon.hpp"
+#include "jstring.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CSelector : public CXSDNode
+{
+public:
+
+    virtual ~CSelector()
+    {
+    }
+
+    virtual void dump(::std::ostream &cout, unsigned int offset = 0) const;
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+
+    virtual void getDocumentation(::StringBuffer &strDoc) const
+    {
+        UNIMPLEMENTED;
+    }
+
+    static CSelector* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+    GETTERSETTER(ID)
+    GETTERSETTER(XPath)
+
+protected:
+
+    CSelector(CXSDNodeBase* pParentNode) : CXSDNode::CXSDNode(pParentNode, XSD_SELECTOR)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_SELECTOR_HPP_

+ 119 - 0
configuration/configurator/SchemaSequence.cpp

@@ -0,0 +1,119 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include <cassert>
+#include "jptree.hpp"
+#include "XMLTags.h"
+#include "SchemaSequence.hpp"
+#include "SchemaElement.hpp"
+#include "JSONMarkUp.hpp"
+
+using namespace CONFIGURATOR;
+
+#define StringBuffer ::StringBuffer
+#define IPropertyTree ::IPropertyTree
+
+const CXSDNodeBase* CSequence::getNodeByTypeAndNameDescending(NODE_TYPES eNodeType, const char *pName) const
+{
+    const CXSDNodeBase* pMatchingNode = NULL;
+
+    if (eNodeType == this->getNodeType() && (pName != NULL ? !strcmp(pName, this->getNodeTypeStr()) : true))
+        return this;
+    if (m_pArrayOfElementArrays != NULL)
+        pMatchingNode = m_pArrayOfElementArrays->getNodeByTypeAndNameDescending(eNodeType, pName);
+
+    return pMatchingNode;
+}
+
+CSequence* CSequence::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    CSequence *pSequence = NULL;
+
+    if (pSchemaRoot == NULL)
+        return NULL;
+    if (pSchemaRoot->queryPropTree(xpath) == NULL)
+        return NULL;  // no sequence node
+
+    StringBuffer strXPath(xpath);
+    strXPath.append("/").append(XSD_TAG_ELEMENT);
+
+    CArrayOfElementArrays *pArrayOfElemArrays = CArrayOfElementArrays::load(NULL, pSchemaRoot, strXPath.str());
+
+    if (pArrayOfElemArrays != NULL)
+    {
+        pSequence = new CSequence(pParentNode, pArrayOfElemArrays);
+        pSequence->setXSDXPath(xpath);
+    }
+    SETPARENTNODE(pArrayOfElemArrays, pSequence)
+
+    return pSequence;
+}
+
+void CSequence::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_SEQUENCE_STR, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+
+    if (m_pArrayOfElementArrays != NULL)
+        m_pArrayOfElementArrays->dump(cout, offset);
+
+    QuickOutFooter(cout, XSD_SEQUENCE_STR, offset);
+}
+
+void CSequence::getDocumentation(StringBuffer &strDoc) const
+{
+    if (m_pArrayOfElementArrays != NULL)
+        m_pArrayOfElementArrays->getDocumentation(strDoc);
+}
+
+void CSequence::getJSON(StringBuffer &strJSON, unsigned int offset, int idx) const
+{
+    if (m_pArrayOfElementArrays != NULL)
+    {
+        m_pArrayOfElementArrays->getJSON(strJSON, offset);
+    }
+}
+
+void CSequence::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    if (m_pArrayOfElementArrays != NULL)
+        m_pArrayOfElementArrays->populateEnvXPath(strXPath, index);
+
+    this->setEnvXPath(strXPath);
+}
+
+void CSequence::loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+{
+    if (m_pArrayOfElementArrays != NULL)
+        m_pArrayOfElementArrays->loadXMLFromEnvXml(pEnvTree);
+}
+
+bool CSequence::hasChildElements() const
+{
+    if (this->m_pArrayOfElementArrays->length() > 0)
+    {
+        for(int i = 0; i < m_pArrayOfElementArrays->ordinality(); i++)
+        {
+            if (m_pArrayOfElementArrays->item(i).length() > 0)
+                return true;
+        }
+    }
+    return false;
+}

+ 56 - 0
configuration/configurator/SchemaSequence.hpp

@@ -0,0 +1,56 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_SEQUENCE_HPP_
+#define _SCHEMA_SEQUENCE_HPP_
+
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CArrayOfElementArrays;
+
+class CSequence : public CXSDNode
+{
+public:
+
+    CSequence(CXSDNodeBase* pParentNode = NULL, CArrayOfElementArrays* pArrayOfElemArrays = NULL) : CXSDNode::CXSDNode(pParentNode, XSD_SEQUENCE), m_pArrayOfElementArrays(pArrayOfElemArrays)
+    {
+    }
+    virtual ~CSequence()
+    {
+    }
+    virtual const CXSDNodeBase* getNodeByTypeAndNameDescending(NODE_TYPES eNodeType, const char *pName) const;
+    virtual void dump(::std::ostream& cout, unsigned int offset  = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const;
+    virtual void getJSON(::StringBuffer &strJSON, unsigned int offset = 0, int idx = -1) const;
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+    bool hasChildElements() const;
+
+    static CSequence* load(CXSDNodeBase* pRootNode, const ::IPropertyTree *pSchemaRoot, const char* xpath = NULL);
+
+protected:
+
+    CArrayOfElementArrays *m_pArrayOfElementArrays;
+
+private:
+};
+
+}
+#endif // _SCHEMA_SEQUENCE_HPP_

+ 81 - 0
configuration/configurator/SchemaSimpleContent.cpp

@@ -0,0 +1,81 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaSimpleContent.hpp"
+#include "SchemaAnnotation.hpp"
+#include "SchemaExtension.hpp"
+#include "SchemaRestriction.hpp"
+
+using namespace CONFIGURATOR;
+
+#define IPropertyTree ::IPropertyTree
+
+CSimpleContent* CSimpleContent::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    if (pParentNode == NULL || pSchemaRoot == NULL)
+        return NULL;
+
+    CExtension *pExtension = NULL;
+    CAnnotation *pAnnotation = NULL;
+    CRestriction *pRestriction = NULL;
+    IPropertyTree *pTree = pSchemaRoot->queryPropTree(xpath);
+    StringBuffer strXPathExt(xpath);
+    strXPathExt.append("/").append(XSD_TAG_EXTENSION);
+
+    if (pSchemaRoot->queryPropTree(strXPathExt.str()) != NULL)
+    {
+        pExtension = CExtension::load(NULL, pSchemaRoot, strXPathExt.str());
+
+        if (pExtension != NULL)
+            pExtension->initExtension();
+    }
+
+    strXPathExt.set(xpath);
+    strXPathExt.append("/").append(XSD_TAG_ANNOTATION);
+
+    if (pSchemaRoot->queryPropTree(strXPathExt.str()) != NULL)
+        pAnnotation = CAnnotation::load(NULL, pSchemaRoot, strXPathExt.str());
+
+    strXPathExt.set(xpath);
+    strXPathExt.append("/").append(XSD_TAG_RESTRICTION);
+
+    if (pSchemaRoot->queryPropTree(strXPathExt.str()) != NULL)
+        pRestriction = CRestriction::load(NULL, pSchemaRoot, strXPathExt.str());
+
+    const char* pID =  NULL;
+    pID = pTree->queryProp(XML_ATTR_ID);
+
+    CSimpleContent *pSimpleContent = new CSimpleContent(pParentNode, pID);
+
+    SETPARENTNODE(pExtension, pSimpleContent);
+    SETPARENTNODE(pAnnotation, pSimpleContent);
+    SETPARENTNODE(pRestriction, pSimpleContent);
+
+    return pSimpleContent;
+}
+
+CSimpleContent::~CSimpleContent()
+{
+    delete m_pRestriction;
+    delete m_pAnnotation;
+    delete m_pExtension;
+}
+
+bool CSimpleContent::checkConstraint(const char *pValue) const
+{
+    return true;
+}

+ 90 - 0
configuration/configurator/SchemaSimpleContent.hpp

@@ -0,0 +1,90 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_SIMPLECONTENT_HPP_
+#define _SCHEMA_SIMPLECONTENT_HPP_
+
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CRestriction;
+class CExtension;
+class CAnnotation;
+
+class CSimpleContent : public CXSDNode
+{
+    GETTERSETTER(ID)
+
+public:
+
+    virtual ~CSimpleContent();
+    bool checkConstraint(const char *pValue) const;
+
+    const CRestriction* getRestriction() const
+    {
+        return m_pRestriction;
+    }
+    const CAnnotation* getAnnotation() const
+    {
+        return m_pAnnotation;
+    }
+    const CExtension* getExtension() const
+    {
+        return m_pExtension;
+    }
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const
+    {
+        UNIMPLEMENTED;
+    }
+    virtual void getDocumentation(StringBuffer &strDoc) const
+    {
+        UNIMPLEMENTED;
+    }
+    virtual const char* getXML(const char* /*pComponent*/)
+    {
+        UNIMPLEMENTED;
+        return NULL;
+    }
+    virtual void populateEnvXPath(StringBuffer strXPath, unsigned int index = 1)
+    {
+        UNIMPLEMENTED;
+    }
+    virtual void loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+    {
+        UNIMPLEMENTED;
+    }
+    static CSimpleContent* load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath);
+
+protected:
+
+    CRestriction *m_pRestriction;
+    CAnnotation *m_pAnnotation;
+    CExtension *m_pExtension;
+
+private:
+
+    CSimpleContent(CXSDNodeBase* pParentNode = NULL, const char* pID = NULL) : CXSDNode::CXSDNode(pParentNode, XSD_SIMPLE_CONTENT), m_strID(pID), m_pRestriction(NULL),
+        m_pAnnotation(NULL), m_pExtension(NULL)
+    {
+    }
+};
+
+}
+
+#endif // _SCHEMA_SIMPLECONTENT_HPP_

+ 198 - 0
configuration/configurator/SchemaSimpleType.cpp

@@ -0,0 +1,198 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "jptree.hpp"
+#include "XMLTags.h"
+#include "SchemaSimpleType.hpp"
+#include "SchemaRestriction.hpp"
+#include "ConfigSchemaHelper.hpp"
+#include "SchemaMapManager.hpp"
+#include "jlib.hpp"
+
+using namespace CONFIGURATOR;
+
+#define StringBuffer ::StringBuffer
+#define IPropertyTree ::IPropertyTree
+
+CXSDNodeBase* CSimpleType::getNodeByTypeAndNameAscending(NODE_TYPES eNodeType, const char *pName)
+{
+    return (this->checkSelf(eNodeType, pName, this->getName()) ? this : NULL);
+}
+
+CXSDNodeBase* CSimpleType::getNodeByTypeAndNameDescending(NODE_TYPES eNodeType, const char *pName)
+{
+    return (this->checkSelf(eNodeType, pName, this->getName()) ? this : NULL);
+}
+
+void CSimpleType::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_SIMPLE_TYPE_STR, offset);
+    QUICK_OUT_2(Name);
+    QUICK_OUT_2(ID);
+    QUICK_OUT(cout, XSDXPath,   offset);
+    QUICK_OUT(cout, EnvXPath,  offset);
+    QUICK_OUT(cout, EnvValueFromXML,  offset);
+
+    if (m_pRestriction != NULL)
+        m_pRestriction->dump(cout, offset);
+
+    QuickOutFooter(cout, XSD_SIMPLE_TYPE_STR, offset);
+}
+
+void CSimpleType::getDocumentation(StringBuffer &strDoc) const
+{
+    if (m_pRestriction != NULL)
+        m_pRestriction->getDocumentation(strDoc);
+}
+
+void CSimpleType::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    this->setEnvXPath(strXPath);
+
+    if (this->m_pRestriction != NULL)
+        this->m_pRestriction->populateEnvXPath(strXPath);
+}
+
+void CSimpleType::loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+{
+    assert(pEnvTree != NULL);
+
+    if (this->m_pRestriction != NULL)
+        this->m_pRestriction->loadXMLFromEnvXml(pEnvTree);
+}
+
+CSimpleType* CSimpleType::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+
+    if (pSchemaRoot == NULL || pParentNode == NULL)
+        return NULL;
+
+    IPropertyTree *pTree = pSchemaRoot->queryPropTree(xpath);
+
+    if (pTree == NULL)
+        return NULL;
+
+    const char* pName =  NULL;
+    const char* pID =  NULL;
+
+    pName = pTree->queryProp(XML_ATTR_NAME);
+    pID = pTree->queryProp(XML_ATTR_ID);
+
+    CSimpleType* pSimpleType = new CSimpleType(pParentNode, pName,pID);
+    pSimpleType->setXSDXPath(xpath);
+    assert(pSimpleType != NULL);
+
+    if (pSimpleType == NULL)
+        return NULL;
+
+    StringBuffer strXPathExt(xpath);
+    strXPathExt.append("/").append(XSD_TAG_RESTRICTION);
+
+    CRestriction *pRestriction = CRestriction::load(pSimpleType, pSchemaRoot, strXPathExt.str());
+
+    if (pRestriction != NULL)
+        pSimpleType->setRestriciton(pRestriction);
+    if (pName != NULL)
+        CConfigSchemaHelper::getInstance()->getSchemaMapManager()->setSimpleTypeWithName(pName, pSimpleType);
+
+    return pSimpleType;
+}
+
+const char* CSimpleType::getXML(const char* /*pComponent*/)
+{
+    if (m_strXML.length () == 0)
+    {
+        m_strXML.append("<").append(getName()).append("\n");
+        m_strXML.append("<").append(getID()).append("\n");
+
+        if (m_pRestriction != NULL)
+            m_strXML.append(m_pRestriction->getXML(NULL));
+
+        m_strXML.append("/>\n");
+    }
+    return m_strXML.str();
+}
+
+bool CSimpleType::checkConstraint(const char *pValue) const
+{
+    if (this->getRestriction() == NULL)
+        return true;
+    else
+        return this->getRestriction()->checkConstraint(pValue);
+}
+
+void CSimpleTypeArray::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_SIMPLE_TYPE_ARRAY_STR, offset);
+    QUICK_OUT(cout, XSDXPath, offset);
+    QUICK_OUT(cout, EnvXPath,  offset);
+    QUICK_OUT(cout, EnvValueFromXML,  offset);
+    QUICK_OUT_ARRAY(cout, offset);
+    QuickOutFooter(cout, XSD_SIMPLE_TYPE_ARRAY_STR, offset);
+}
+
+CSimpleTypeArray* CSimpleTypeArray::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pParentNode != NULL);
+    assert(pSchemaRoot != NULL);
+    if (pSchemaRoot == NULL)
+        return NULL;
+
+    CSimpleTypeArray *pSimpleTypeArray = new CSimpleTypeArray(pParentNode);
+    pSimpleTypeArray->setXSDXPath(xpath);
+
+    Owned<IPropertyTreeIterator> elemIter = pSchemaRoot->getElements(xpath);
+
+    int count = 1;
+    ForEach(*elemIter)
+    {
+        StringBuffer strXPathExt(xpath);
+        strXPathExt.appendf("[%d]", count);
+
+        CSimpleType *pSimpleType = CSimpleType::load(pSimpleTypeArray, pSchemaRoot, strXPathExt.str());
+
+        assert(pSimpleType != NULL);
+        pSimpleTypeArray->append(*pSimpleType);
+
+        count++;
+    }
+    return pSimpleTypeArray;
+}
+
+void CSimpleTypeArray::getDocumentation(StringBuffer &strDoc) const
+{
+    QUICK_DOC_ARRAY(strDoc);
+}
+
+void CSimpleTypeArray::populateEnvXPath(StringBuffer strXPath, unsigned int index)
+{
+    assert(index == 1);  // Only 1 array of elements per node
+
+    this->setEnvXPath(strXPath);
+    QUICK_ENV_XPATH(strXPath)
+}
+
+void CSimpleTypeArray::loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+{
+    assert(pEnvTree != NULL);
+    QUICK_LOAD_ENV_XML(pEnvTree)
+}

+ 113 - 0
configuration/configurator/SchemaSimpleType.hpp

@@ -0,0 +1,113 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_SIMPLE_TYPE_HPP_
+#define _SCHEMA_SIMPLE_TYPE_HPP_
+
+#include "jstring.hpp"
+#include "jarray.hpp"
+#include "SchemaCommon.hpp"
+#include "SchemaRestriction.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CRestriction;
+
+class CSimpleType : public CXSDNode
+{
+public:
+
+    virtual ~CSimpleType()
+    {
+    }
+
+    virtual CXSDNodeBase* getNodeByTypeAndNameAscending(NODE_TYPES eNodeType, const char *pName);
+    virtual CXSDNodeBase* getNodeByTypeAndNameDescending(NODE_TYPES eNodeType, const char *pName);
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(StringBuffer &strDoc) const;
+    virtual void populateEnvXPath(StringBuffer strXPath, unsigned int index = 1);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+    virtual const char* getXML(const char* /*pComponent*/);
+
+    static CSimpleType* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+    GETTERSETTER(Name)
+    GETTERSETTER(ID)
+
+    const CRestriction* getRestriction() const
+    {
+        return m_pRestriction;
+    }
+
+    void setRestriciton(CRestriction *pRestriction)
+    {
+        if (m_pRestriction != NULL)
+        {
+            m_pRestriction->Release();
+            m_pRestriction = NULL;
+        }
+        m_pRestriction = pRestriction;
+    }
+
+    bool checkConstraint(const char *pValue) const;
+
+protected:
+
+    CSimpleType(CXSDNodeBase* pRootNode, const char* pName = NULL, const char* pID = NULL, CRestriction* pRestriction = NULL) : CXSDNode::CXSDNode(pRootNode, XSD_SIMPLE_TYPE),m_strName(pName), m_strID(pID), m_pRestriction(pRestriction)
+    {
+    }
+
+    CRestriction* m_pRestriction;
+
+private:
+
+    CSimpleType() : CXSDNode::CXSDNode(NULL)
+    {
+    }
+};
+
+class CSimpleTypeArray : public CIArrayOf<CSimpleType>, public InterfaceImpl, public CXSDNodeBase
+{
+public:
+
+    CSimpleTypeArray(CXSDNodeBase* pParentNode) : CXSDNodeBase::CXSDNodeBase(pParentNode, XSD_SIMPLE_TYPE_ARRAY)
+    {
+    }
+
+    virtual ~CSimpleTypeArray()
+    {
+    }
+
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(StringBuffer &strDoc) const;
+    virtual void populateEnvXPath(StringBuffer strXPath, unsigned int index = 1);
+    virtual void loadXMLFromEnvXml(const ::IPropertyTree *pEnvTree);
+
+    static CSimpleTypeArray* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+protected:
+
+private:
+
+    CSimpleTypeArray() : CXSDNodeBase::CXSDNodeBase(NULL)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_SIMPLE_TYPE_HPP_

+ 31 - 0
configuration/configurator/SchemaTotalDigits.cpp

@@ -0,0 +1,31 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaTotalDigits.hpp"
+
+using namespace CONFIGURATOR;
+
+CTotalDigits* CTotalDigits::load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    CTotalDigits *pTotalDigits = CXSDNodeWithRestrictions<CTotalDigits>::load(pParentNode, pSchemaRoot, xpath);
+
+    if (pTotalDigits == NULL)
+        return NULL;
+
+    pTotalDigits->setTotalDigits(pTotalDigits->getValue());
+    return pTotalDigits;
+}

+ 46 - 0
configuration/configurator/SchemaTotalDigits.hpp

@@ -0,0 +1,46 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_TOTAL_DIGITS_HPP_
+#define _SCHEMA_TOTAL_DIGITS_HPP_
+
+#include "SchemaCommon.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CTotalDigits : public CXSDNodeWithRestrictions<CTotalDigits>
+{
+    friend class CXSDNodeWithRestrictions<CTotalDigits>;
+public:
+
+    virtual ~CTotalDigits()
+    {
+    }
+    static CTotalDigits* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+    GETTERSETTERINT(TotalDigits)
+
+protected:
+
+    CTotalDigits(CXSDNodeBase* pParentNode = NULL) : CXSDNodeWithRestrictions<CTotalDigits>::CXSDNodeWithRestrictions(pParentNode, XSD_TOTAL_DIGITS), m_nTotalDigits(-1)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_TOTAL_DIGITS_HPP_

+ 113 - 0
configuration/configurator/SchemaUnique.cpp

@@ -0,0 +1,113 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "SchemaUnique.hpp"
+
+using namespace CONFIGURATOR;
+
+CUnique* CUnique::load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    assert(pParentNode != NULL);
+    assert(pParentNode->getNodeType() == XSD_UNIQUE_ARRAY);
+
+    if (pSchemaRoot == NULL || pParentNode == NULL) 
+        return NULL;    // TODO: Throw Exception
+
+    CUnique *pUnique = NULL;
+
+    if (xpath != NULL && *xpath != 0)
+    {
+        IPropertyTree* pTree = pSchemaRoot->queryPropTree(xpath);
+
+        if (pTree == NULL)
+            return NULL;
+
+        const char* pName = pSchemaRoot->getPropTree(xpath)->queryProp(XML_ATTR_NAME);
+        assert(pName != NULL && *pName != 0);
+
+        if (pName == NULL || *pName == 0)
+            assert(!"Throw Exception name can not be empty");     // TODO: throw exception
+        else
+        {
+            pUnique = new CUnique(pParentNode);
+            pUnique->setXSDXPath(xpath);
+        }
+
+        const char *pID = pSchemaRoot->getPropTree(xpath)->queryProp(XML_ATTR_ID);
+        if (pID != NULL)
+            pUnique->setID(pID);
+    }
+    return pUnique;
+}
+
+void CUnique::dump(::std::ostream& cout, unsigned int offset) const
+{
+    offset += STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_UNIQUE_STR, offset);
+    QUICK_OUT(cout, ID, offset);
+    QUICK_OUT(cout, Name, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QuickOutFooter(cout, XSD_UNIQUE_STR, offset);
+}
+
+CUniqueArray* CUniqueArray::load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath)
+{
+    assert(pSchemaRoot != NULL);
+    if (pSchemaRoot == NULL || xpath == NULL)
+        return NULL;
+
+    Owned<IPropertyTreeIterator> attributeIter = pSchemaRoot->getElements(xpath, ipt_ordered);
+    StringBuffer strXPathExt(xpath);
+
+    CUniqueArray *pUniqueArray = new CUniqueArray(pParentNode);
+    pUniqueArray->setXSDXPath(xpath);
+
+    int count = 1;
+    ForEach(*attributeIter)
+    {
+        strXPathExt.clear().append(xpath).appendf("[%d]",count);
+
+        CUnique *pUnique = CUnique::load(pUniqueArray, pSchemaRoot, strXPathExt.str());
+
+        if (pUnique != NULL)
+            pUniqueArray->append(*pUnique);
+
+        count++;
+    }
+
+    if (pUniqueArray->length() == 0)
+    {
+        delete pUniqueArray;
+        pUniqueArray = NULL;
+    }
+    return pUniqueArray;
+}
+
+void CUniqueArray::dump(::std::ostream &cout, unsigned int offset) const
+{
+    offset+= STANDARD_OFFSET_1;
+
+    QuickOutHeader(cout, XSD_UNIQUE_ARRAY_STR, offset);
+    QUICK_OUT(cout, XSDXPath,  offset);
+    QUICK_OUT(cout, EnvXPath,  offset);
+    QUICK_OUT_ARRAY(cout, offset);
+    QuickOutFooter(cout, XSD_UNIQUE_ARRAY_STR, offset);
+}
+
+

+ 93 - 0
configuration/configurator/SchemaUnique.hpp

@@ -0,0 +1,93 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef _SCHEMA_UNIQUE_HPP_
+#define _SCHEMA_UNIQUE_HPP_
+
+#include "SchemaCommon.hpp"
+#include "SchemaKey.hpp"
+#include "jstring.hpp"
+
+namespace CONFIGURATOR
+{
+
+class CSchemaUnique;
+
+class CUnique : public CXSDNode
+{
+public:
+
+    virtual ~CUnique()
+    {
+    }
+
+    virtual void dump(::std::ostream &cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const
+    {
+        UNIMPLEMENTED;
+    }
+
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1)
+    {
+        UNIMPLEMENTED;
+    }
+    static CUnique* load(CXSDNodeBase* pParentNode, const ::IPropertyTree *pSchemaRoot, const char* xpath);
+
+    GETTERSETTER(ID)
+    GETTERSETTER(Name)
+
+protected:
+
+    CUnique(CXSDNodeBase *pParentNode) : CXSDNode::CXSDNode(pParentNode, XSD_UNIQUE)
+    {
+    }
+
+};
+
+class CUniqueArray : public CIArrayOf<CUnique>, public InterfaceImpl, public CXSDNodeBase
+{
+public:
+
+    virtual ~CUniqueArray()
+    {
+    }
+
+    virtual void dump(::std::ostream& cout, unsigned int offset = 0) const;
+    virtual void getDocumentation(::StringBuffer &strDoc) const
+    {
+        UNIMPLEMENTED;
+    }
+
+    virtual void populateEnvXPath(::StringBuffer strXPath, unsigned int index = 1)
+    {
+        UNIMPLEMENTED;
+    }
+    virtual void loadXMLFromEnvXml(const IPropertyTree *pEnvTree)
+    {
+        UNIMPLEMENTED;
+    }
+    static CUniqueArray* load(CXSDNodeBase* pParentNode, const IPropertyTree *pSchemaRoot, const char* xpath);
+
+protected:
+
+    CUniqueArray(CXSDNodeBase* pParentNode = NULL) : CXSDNodeBase::CXSDNodeBase(pParentNode, XSD_UNIQUE_ARRAY)
+    {
+    }
+};
+
+}
+#endif // _SCHEMA_UNIQUE_HPP_

+ 0 - 0
configuration/configurator/SchemaWhiteSpace.cpp


Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio