413 lines
17 KiB
C++
413 lines
17 KiB
C++
#pragma once
|
|
|
|
#include "dtcore/inc/dtdefinitions.h"
|
|
#include "dtcore/inc/dtstring.h"
|
|
#include "dtcore/inc/dtvector.h"
|
|
#include "dtcore/inc/dtmap.h"
|
|
#include "dtcore/inc/dtresolvable.h"
|
|
#include "dtcore/inc/dttemplatedescriptor.h"
|
|
#include "dtcore/inc/dtchrono.h"
|
|
|
|
namespace dt
|
|
{
|
|
|
|
#define DT_XML_ISSUE(id, node, msg) \
|
|
do \
|
|
{ \
|
|
dt::String _msg; \
|
|
_msg << msg; \
|
|
node->AddIssue(dt::XmlIssue(id, _msg)); \
|
|
} while (0)
|
|
|
|
#define DT_XML_DEPRECATED_NODE(id, node, name, msg) \
|
|
do \
|
|
{ \
|
|
if (node->HasChildByName(name)) \
|
|
{ \
|
|
dt::String _msg; \
|
|
_msg << "Child node '" << name << "' is deprecated. " << msg; \
|
|
node->AddIssue(dt::XmlIssue(id, _msg)); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define DT_XML_DEPRECATED_ATTRIBUTE(id, node, attribute, msg) \
|
|
do \
|
|
{ \
|
|
if (node->HasAttribute(attribute)) \
|
|
{ \
|
|
dt::String _msg; \
|
|
_msg << "Attribute '" << attribute << "' is deprecated. " << msg; \
|
|
node->AddIssue(dt::XmlIssue(id, _msg)); \
|
|
} \
|
|
} while (0)
|
|
|
|
enum class XmlIssueId : int
|
|
{
|
|
// Errors
|
|
ErrorFirst = 10000,
|
|
|
|
// Agency Configuration
|
|
ErrorAgencyResourcePlatformEmpty = 10000,
|
|
ErrorAgencyResourceNameEmpty = 10001,
|
|
ErrorAgencyResourceAvailabilityInvalid = 10002,
|
|
|
|
// Farm Configuration
|
|
ErrorFarmDatabaseMaxStorageSizeInvalid = 11000,
|
|
ErrorFarmContactNotFound = 11001,
|
|
ErrorFarmContactReferenceNotFound = 11002,
|
|
ErrorFarmReportTemplateLoadingFailed = 11003,
|
|
ErrorFarmVersionMatcherTitleModeInvalid = 11004,
|
|
ErrorFarmVersionMatcherSortingOptionInvalid = 11005,
|
|
ErrorFarmVersionMatcherSortingOptionColumnInvalid = 11006,
|
|
ErrorFarmVersionMatcherSortingOptionOrderInvalid = 11007,
|
|
ErrorFarmCloudStorageCannotCustomizeProjectDTest = 11008,
|
|
ErrorFarmShareModeUnknown = 11009,
|
|
ErrorFarmJiraPasswordUnresolved = 11010,
|
|
ErrorFarmCloudStoragePasswordUnresolved = 11011,
|
|
|
|
// Project Configuration
|
|
ErrorProjectShellCommandExitCodeInvalid = 12000,
|
|
ErrorProjectShellCommandFailMessageInvalid = 12001,
|
|
ErrorProjectShellCommandProgressMessageInvalid = 12002,
|
|
ErrorProjectShellCommandPrerequisiteInvalid = 12003,
|
|
ErrorProjectShellCommandTypeInvalid = 12004,
|
|
ErrorProjectShellCommandTypeEmpty = 12005,
|
|
ErrorProjectShellCommandRunModeInvalid = 12006,
|
|
ErrorProjectShellCommandFailureCategoryAndExitCodeSet = 12007,
|
|
ErrorProjectShellCommandFailureFailureCategoryHealthRescheduleSet = 12008,
|
|
ErrorProjectShellCommandStoredArtefactMaxSizeTooLarge = 12009,
|
|
ErrorProjectShellCommandCommandOverridenForGlobalCommand = 12010,
|
|
ErrorProjectShellCommandGlobalCreationFailed = 12011,
|
|
ErrorProjectDeploymentDefaultDuplicate = 12012,
|
|
ErrorProjectTokenLoanStrategyInvalid = 12013,
|
|
ErrorProjectTokenCountOutOfRange = 12014,
|
|
ErrorProjectTokenCounterButNoCount = 12015,
|
|
ErrorProjectTokenStartButNoCount = 12016,
|
|
ErrorProjectProfileDefaultDuplicate = 12017,
|
|
ErrorProjectProfileNameEmpty = 12018,
|
|
ErrorProjectCustomFailureCategoryBuiltInOverride = 12019,
|
|
ErrorProjectCustomFailureCategoryPriorityInvalid = 12020,
|
|
ErrorProjectCustomFailureCategoryRetryInvalid = 12021,
|
|
ErrorProjectCustomFailureCategoryCompletionInvalid = 12022,
|
|
ErrorProjectCustomFailureCategoryResourceHealthChangeInvalid = 12023,
|
|
ErrorProjectTargetDefaultShellCommandRunModeInvalid = 12024,
|
|
ErrorProjectExpectedIssueAgentInvalid = 12025,
|
|
ErrorProjectExpectedIssueTryInvalid = 12026,
|
|
ErrorProjectExpectedIssueTypeInvalid = 12027,
|
|
//ErrorProjectTestDependencyMasterOrSubTest = 12028, // deleted
|
|
ErrorProjectTestPrerequisiteNotFound = 12029,
|
|
ErrorProjectTestNameContainsDots = 12030,
|
|
ErrorProjectTestAlreadyDefined = 12031,
|
|
ErrorProjectTestElevatedInvalid = 12032,
|
|
ErrorProjectTestPrerequisiteModeInvalid = 12033,
|
|
ErrorProjectTestMaintainerCantBeEmpty = 12034,
|
|
ErrorProjectTestDependencyTargetMapOverrideUnspecified = 12035,
|
|
ErrorProjectTestExecutionModeInvalid = 12036,
|
|
ErrorProjectTestTokenNameEmpty = 12037,
|
|
ErrorProjectTestScriptUserMappingInvalid = 12038,
|
|
ErrorProjectTestTryModeInvalid = 12039,
|
|
ErrorProjectTestAgentNeedInvalid = 12040,
|
|
ErrorProjectTestAgentNeedTargetInvalid = 12041,
|
|
ErrorProjectTestAgentNeedExclusiveModeInvalid = 12042,
|
|
ErrorProjectSemaphoreReentranceInvalid = 12043,
|
|
ErrorProjectSemaphoreTypeInvalid = 12044,
|
|
ErrorProjectSemaphoreNameInvalid = 12045,
|
|
ErrorProjectSuiteNotFound = 12046,
|
|
ErrorProjectSuiteUseOnOutterFilter = 12047,
|
|
ErrorProjectSuiteDuplicate = 12048,
|
|
ErrorProjectSuiteFilterNameInvalid = 12049,
|
|
ErrorProjectSuiteFilterTestNoFound = 12050,
|
|
ErrorProjectSuiteFilterGenericInvalid = 12051,
|
|
ErrorProjectSuiteFilterGenericAvailabilityInvalid = 12052,
|
|
ErrorProjectContactReferenceNotFound = 12053,
|
|
ErrorProjectBatchOutcomeModeInvalid = 12054,
|
|
ErrorProjectBatchOutcomeWarningModeInvalid = 12055,
|
|
ErrorProjectScriptFunctionCustomVariableNotAllowed = 12056,
|
|
ErrorProjectTryModeInvalid = 12057,
|
|
ErrorProjectNameInvalid = 12058,
|
|
ErrorProjectPrerequisiteModeInvalid = 12059,
|
|
ErrorProjectExecutionModeInvalid = 12060,
|
|
ErrorProjectStoredArtefactMaxSizeTooLarge = 12061,
|
|
ErrorProjectScriptDeclarationSourcePathNotProvided = 12062,
|
|
ErrorProjectNewFileTemplateEmpty = 12063,
|
|
ErrorProjectCustomSettingDefaultValueNewLine = 12064,
|
|
ErrorProjectCustomSettingIdDuplicate = 12065,
|
|
ErrorProjectCustomSettingTypeInvalid = 12066,
|
|
ErrorProjectCustomSettingValueOnTypeInvalid = 12067,
|
|
ErrorProjectCustomSettingValueWithNewLine = 12068,
|
|
ErrorProjectCustomSettingComboBoxWithNoValue = 12069,
|
|
ErrorProjectCustomSettingComboBoxDefaultValueInvalid = 12070,
|
|
ErrorProjectQuarantineIssueIdNotFound = 12071,
|
|
ErrorProjectQuarantineReasonNotFound = 12072,
|
|
ErrorProjectTestNameEmpty = 12073,
|
|
ErrorProjectSuiteMultipleFilters = 12074,
|
|
ErrorProjectShellCommandArtefactTypeInvalid = 12075,
|
|
ErrorProjectBloombergReportTypeInvalid = 12076,
|
|
|
|
// Parser
|
|
ErrorParserTemplateReferenceCircular = 13000,
|
|
ErrorParserAttributeNotFound = 13001,
|
|
ErrorParserAttributeUnknown = 13002,
|
|
ErrorParserAttributeIntegerInvalid = 13003,
|
|
ErrorParserAttributeFloatInvalid = 13004,
|
|
ErrorParserNodeNotFound = 13005,
|
|
ErrorParserNodeUnknown = 13006,
|
|
ErrorParserIncludeFileNotFound = 13007,
|
|
ErrorParserIncludeNoFileFound = 13008,
|
|
ErrorParserIncludeInvalid = 13009,
|
|
ErrorParserTemplateNotFound = 13010,
|
|
ErrorParserTemplateDuplicateFound = 13011,
|
|
ErrorParserTemplateDuplicateReferer = 13012,
|
|
|
|
ErrorLast = 19999,
|
|
|
|
// Warnings
|
|
WarningFirst = 20000,
|
|
|
|
// Agency Configuration
|
|
WarningAgencyResourceMandatoryCapabilityDeprecated = 20000,
|
|
|
|
// Farm Configuration
|
|
WarningFarmDatabaseNameDeprecated = 21000,
|
|
WarningFarmMaxTestQueueInspectionCountDeprecated = 21001,
|
|
WarningFarmIncrementalSchedulingCountPerFrameDeprecated = 21002,
|
|
WarningFarmVersionMatcherContactDeprecated = 21003,
|
|
WarningFarmStartPortDeprecated = 21004,
|
|
WarningFarmTCPPortDeprecated = 21005,
|
|
WarningFarmJiraPasswordExplicit = 21006,
|
|
// WarningFarmJiraPasswordUnresolved = 21007,, Moved to Error
|
|
WarningFarmCloudStoragePasswordExplicit = 21008,
|
|
// WarningFarmCloudStoragePasswordUnresolved = 21009, Moved to Error
|
|
|
|
// Project Configuration
|
|
WarningProjectShellCommandDeploymentFilterDeprecated = 22000,
|
|
WarningProjectShellCommandIsAffectingResourceHealthOnFailureDeprecated = 22001,
|
|
WarningProjectShellCommandRescheduleOnFailureDeprecated = 22001,
|
|
WarningProjectVariableDeploymentFilterDeprecated = 22002,
|
|
WarningProjectTestDependencyDeprecated = 22003,
|
|
WarningProjectTestAgencyReservationPlatformDeprecated = 22004,
|
|
WarningProjectTestNumAgentDeprecated = 22005,
|
|
WarningProjectSuiteFilterNameDeprecated = 22006,
|
|
WarningProjectTargetPackageShareTrustyNameDeprecated = 22007,
|
|
WarningProjectTestManagementPasswordExplicit = 22008,
|
|
WarningProjectTestManagementPasswordUnresolved = 22009,
|
|
WarningProjectShellCommandArtefactTypeDeprecated = 22010,
|
|
WarningProjectTestAgentNeedUseAllDeprecated = 22011,
|
|
|
|
WarningLast = 29999
|
|
};
|
|
|
|
enum class XmlIssueType
|
|
{
|
|
Unknown,
|
|
Error,
|
|
Warning
|
|
};
|
|
|
|
class XmlIssue
|
|
{
|
|
public:
|
|
DT_CORE_DLL_ENTRY XmlIssue(XmlIssueId type, const String& header);
|
|
|
|
DT_CORE_DLL_ENTRY XmlIssueType GetType() const;
|
|
DT_CORE_DLL_ENTRY XmlIssueId GetId() const { return m_Id; }
|
|
DT_CORE_DLL_ENTRY const String& GetHeader() const { return m_Header; }
|
|
|
|
private:
|
|
String m_Header;
|
|
XmlIssueId m_Id;
|
|
};
|
|
|
|
class XmlNode;
|
|
typedef Vector<XmlNode*> XmlNodes;
|
|
typedef Map<String, String> XmlAttributes;
|
|
|
|
class XmlNode : public Serializable
|
|
{
|
|
public:
|
|
|
|
DT_CORE_DLL_ENTRY virtual ~XmlNode(){}
|
|
DT_CORE_DLL_ENTRY virtual const String& GetName() const = 0;
|
|
DT_CORE_DLL_ENTRY virtual const XmlNodes& GetChildren() const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool HasChildByName(const String& name) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool GetChildrenByName(const String& name, XmlNodes& out) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool TryGetChildrenByName(const String& name, XmlNodes& out) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool GetFirstChildByName(const String& name, XmlNode*& out) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool TryGetFirstChildByName(const String& name, XmlNode*& out) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool TryGetFirstChildByFileNameAndLine(const String& originFile, int originLine, XmlNode*& out) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool HasAttribute(const String& name) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool GetAttribute(const String& name, String& out) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool GetAttribute(const String& name, U64& out) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool GetAttribute(const String& name, S64& out) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool GetAttribute(const String& name, int& out) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool GetAttribute(const String& name, float& out) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool GetAttribute(const String& name, bool& out) const = 0;
|
|
template <class Rep, class Period> bool GetAttribute(const String& name, std::chrono::duration<Rep, Period>& out) const;
|
|
template <typename T, typename Param> bool GetAttribute(const String& name, StrongType<T, Param>& out) const;
|
|
DT_CORE_DLL_ENTRY virtual bool TryGetAttribute(const String& name, String& out, const String& defaultValue = String::Blank()) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool TryGetAttribute(const String& name, U64& out, U64 defaultValue = 0) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool TryGetAttribute(const String& name, S64& out, S64 defaultValue = 0) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool TryGetAttribute(const String& name, int& out, int defaultValue = 0) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool TryGetAttribute(const String& name, float& out, float defaultValue = 0.0f) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool TryGetAttribute(const String& name, bool& out, bool defaultValue = false) const = 0;
|
|
template <class Rep, class Period>
|
|
bool TryGetAttribute(const String& name,
|
|
std::chrono::duration<Rep, Period>& out,
|
|
std::chrono::duration<Rep, Period> defaultValue = std::chrono::duration<Rep, Period>::zero()) const;
|
|
template <typename T, typename Param>
|
|
bool TryGetAttribute(const String& name,
|
|
StrongType<T, Param>& out,
|
|
StrongType<T, Param> defaultValue = StrongType<T, Param>(0)) const;
|
|
DT_CORE_DLL_ENTRY virtual const XmlAttributes& GetAttributes() const = 0;
|
|
DT_CORE_DLL_ENTRY virtual const String& GetValue() const = 0;
|
|
DT_CORE_DLL_ENTRY virtual void SetValue(const String& value) = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool HasValue() const = 0;
|
|
DT_CORE_DLL_ENTRY virtual XmlNode* Clone() const = 0;
|
|
DT_CORE_DLL_ENTRY virtual void MarkAsTouched() const = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool IsTouched() const = 0;
|
|
DT_CORE_DLL_ENTRY virtual void MarkAsTouchedRecursive() = 0;
|
|
DT_CORE_DLL_ENTRY virtual bool MarkUntouchedNodesAsError() = 0;
|
|
DT_CORE_DLL_ENTRY virtual void GetLastErrorStrings(Strings& errors) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual void AddIssue(const XmlIssue& issue) = 0;
|
|
DT_CORE_DLL_ENTRY virtual void GetLastWarningStrings(Strings& warnings) const = 0;
|
|
DT_CORE_DLL_ENTRY virtual String ToString() const = 0;
|
|
DT_CORE_DLL_ENTRY virtual String ToStringWithLocations() const = 0;
|
|
DT_CORE_DLL_ENTRY virtual int GetLine() const = 0;
|
|
DT_CORE_DLL_ENTRY virtual const String& GetFilename() const = 0;
|
|
};
|
|
|
|
template <class Rep, class Period> inline
|
|
bool XmlNode::GetAttribute(const String& name, std::chrono::duration<Rep, Period>& out) const
|
|
{
|
|
S64 value;
|
|
if (GetAttribute(name, value))
|
|
{
|
|
out = std::chrono::duration<Rep, Period>(value);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
template <class T, class Param> inline
|
|
bool XmlNode::GetAttribute(const String& name, StrongType<T, Param>& out) const
|
|
{
|
|
T value;
|
|
if (GetAttribute(name, value))
|
|
{
|
|
out = StrongType<T, Param>(value);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
template <class Rep, class Period> inline
|
|
bool XmlNode::TryGetAttribute(const String& name,
|
|
std::chrono::duration<Rep, Period>& out,
|
|
std::chrono::duration<Rep, Period> defaultValue) const
|
|
{
|
|
S64 value;
|
|
if (TryGetAttribute(name, value))
|
|
{
|
|
out = std::chrono::duration<Rep, Period>(value);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
out = defaultValue;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template <class T, class Param > inline
|
|
bool XmlNode::TryGetAttribute(const String& name,
|
|
StrongType<T, Param>& out,
|
|
StrongType<T, Param> defaultValue) const
|
|
{
|
|
T value;
|
|
if (TryGetAttribute(name, value))
|
|
{
|
|
out = StrongType<T, Param>(value);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
out = defaultValue;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
class XmlDocument : public Resolvable
|
|
{
|
|
public:
|
|
DT_CORE_DLL_ENTRY XmlDocument(XmlNode* root = nullptr);
|
|
DT_CORE_DLL_ENTRY virtual ~XmlDocument();
|
|
|
|
DT_CORE_DLL_ENTRY XmlDocument(const XmlDocument& doc);
|
|
DT_CORE_DLL_ENTRY XmlDocument& operator=(const XmlDocument& doc);
|
|
|
|
DT_CORE_DLL_ENTRY XmlNode* GetRoot() const;
|
|
DT_CORE_DLL_ENTRY void Move(XmlNode* root);
|
|
DT_CORE_DLL_ENTRY void Merge(const XmlNode* rhs, bool addSourceFirst = false);
|
|
DT_CORE_DLL_ENTRY void Swap(XmlDocument& other);
|
|
DT_CORE_DLL_ENTRY bool Empty() const;
|
|
|
|
DT_CORE_DLL_ENTRY virtual String GetDecoratedName() const override;
|
|
DT_CORE_DLL_ENTRY virtual const String& GetOriginFile() const override { return m_Root ? m_Root->GetFilename() : String::Blank(); }
|
|
DT_CORE_DLL_ENTRY virtual int GetOriginLine() const override { return m_Root ? m_Root->GetLine() : 0; }
|
|
|
|
DT_CORE_DLL_ENTRY virtual void Serialize(U8 version, Stream& stream) override;
|
|
|
|
private:
|
|
XmlNode* m_Root;
|
|
};
|
|
|
|
DT_CORE_DLL_ENTRY String& operator<<(String& out, const XmlDocument& doc);
|
|
|
|
class XmlParserImpl;
|
|
|
|
enum class XmlParserResult
|
|
{
|
|
FileNoFound,
|
|
Failed,
|
|
Success
|
|
};
|
|
|
|
class XmlParser
|
|
{
|
|
public:
|
|
DT_CORE_DLL_ENTRY XmlParser();
|
|
DT_CORE_DLL_ENTRY ~XmlParser();
|
|
|
|
// Load and parse the specific XML document.
|
|
// Note: This method will resolve <Include> nodes
|
|
DT_CORE_DLL_ENTRY XmlParserResult Load(const String& filename);
|
|
|
|
// Parse the given XML string
|
|
// Note: This method will *not* resolve <Include> nodes
|
|
DT_CORE_DLL_ENTRY XmlParserResult Parse(const String& xmlStr);
|
|
|
|
DT_CORE_DLL_ENTRY void Clear();
|
|
|
|
DT_CORE_DLL_ENTRY const String& GetFilename() const;
|
|
|
|
DT_CORE_DLL_ENTRY const XmlDocument& GetDocument() const;
|
|
|
|
DT_CORE_DLL_ENTRY void Swap(XmlDocument& other);
|
|
|
|
DT_CORE_DLL_ENTRY const TemplateDescriptors& GetTemplateDeclarations() const;
|
|
|
|
DT_CORE_DLL_ENTRY const TemplateDescriptors& GetTemplateReferences() const;
|
|
|
|
DT_CORE_DLL_ENTRY Strings GetFileReferences() const;
|
|
|
|
DT_CORE_DLL_ENTRY String GetLastErrorString() const;
|
|
DT_CORE_DLL_ENTRY String GetLastWarningString() const;
|
|
|
|
private:
|
|
XmlParserImpl* m_Impl;
|
|
|
|
XmlParserResult ValidateParsedDocument(XmlParserResult parsingResult, const XmlDocument& document);
|
|
};
|
|
|
|
}
|
|
|