JD2022-TU1/main/extern/dtest/dtcore/inc/dtxmlparser.h

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);
};
}