Files
2025-05-18 13:04:45 +08:00

137 lines
5.0 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "DirectLinkUriResolver.h"
#include "DirectLinkExtensionModule.h"
#include "DirectLinkExternalSource.h"
#include "IDirectLinkManager.h"
#include "Misc/AutomationTest.h"
namespace UE::DatasmithImporter
{
TSharedPtr<FExternalSource> FDirectLinkUriResolver::GetOrCreateExternalSource(const FSourceUri& Uri) const
{
IDirectLinkManager& DirectLinkManager = IDirectLinkExtensionModule::Get().GetManager();
return DirectLinkManager.GetOrCreateExternalSource(Uri);
}
bool FDirectLinkUriResolver::CanResolveUri(const FSourceUri& Uri) const
{
return Uri.HasScheme(GetDirectLinkScheme());
}
TOptional<FDirectLinkSourceDescription> FDirectLinkUriResolver::TryParseDirectLinkUri(const FSourceUri& Uri)
{
if (Uri.HasScheme(GetDirectLinkScheme()))
{
const FString UriPath(Uri.GetPath());
TArray<FString> PathStrings;
// Try to split the URI path into 4 parts, those parts should correspond to the DirectLink source info.
if (UriPath.ParseIntoArray(PathStrings, TEXT("/")) == 4)
{
FDirectLinkSourceDescription SourceDescription;
SourceDescription.ComputerName = MoveTemp(PathStrings[0]);
SourceDescription.ExecutableName = MoveTemp(PathStrings[1]);
SourceDescription.EndpointName = MoveTemp(PathStrings[2]);
SourceDescription.SourceName = MoveTemp(PathStrings[3]);
TMap<FString, FString> QueryKeyValues = Uri.GetQueryMap();
if (const FString* SourceIdString = QueryKeyValues.Find(GetSourceIdPropertyName()))
{
FGuid SourceId;
LexFromString(SourceId, **SourceIdString);
SourceDescription.SourceId.Emplace(MoveTemp(SourceId));
}
return TOptional<FDirectLinkSourceDescription>(MoveTemp(SourceDescription));
}
}
return TOptional<FDirectLinkSourceDescription>();
}
const FString& FDirectLinkUriResolver::GetDirectLinkScheme()
{
static FString Scheme(TEXT("directlink"));
return Scheme;
}
const FString& FDirectLinkUriResolver::GetSourceIdPropertyName()
{
static FString SourceIdName(TEXT("SourceId"));
return SourceIdName;
}
/**
* Automated test to validate DirectLink URI parsing.
*/
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FDirectLinkUriResolverTests, "Editor.Import.Datasmith.ExternalSource.DirectLink URI Parsing", EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter)
bool FDirectLinkUriResolverTests::RunTest(const FString& Parameters)
{
const FString ComputerName = TEXT("FooComputer");
const FString ExecutableName = TEXT("BarDCC");
const FString EndpointName = TEXT("DatasmithExporter");
const FString SourceName = TEXT("DummySource");
const FGuid RandomGuid = FGuid::NewGuid();
{
const FSourceUri ValidUri = FSourceUri(FDirectLinkUriResolver::GetDirectLinkScheme(), ComputerName / ExecutableName / EndpointName / SourceName);
TOptional<FDirectLinkSourceDescription> ParsedSourceDescription = FDirectLinkUriResolver::TryParseDirectLinkUri(ValidUri);
if (!ParsedSourceDescription.IsSet())
{
AddError(TEXT("Could not parse valid directlink source URI"));
return false;
}
else if (ParsedSourceDescription->ComputerName != ComputerName
|| ParsedSourceDescription->ExecutableName != ExecutableName
|| ParsedSourceDescription->EndpointName != EndpointName
|| ParsedSourceDescription->SourceName != SourceName)
{
AddError(TEXT("Could not parse valid directlink source URI path"));
return false;
}
else if (ParsedSourceDescription->SourceId.IsSet())
{
AddError(TEXT("Parsed a SourceId when there was none"));
return false;
}
}
{
TMap<FString, FString> UriQuery{ {FDirectLinkUriResolver::GetSourceIdPropertyName(), LexToString(RandomGuid)} };
const FSourceUri ValidUriWithSourceId = FSourceUri(FDirectLinkUriResolver::GetDirectLinkScheme(), ComputerName / ExecutableName / EndpointName / SourceName, UriQuery);
TOptional<FDirectLinkSourceDescription> ParsedSourceDescription = FDirectLinkUriResolver::TryParseDirectLinkUri(ValidUriWithSourceId);
if (!ParsedSourceDescription.IsSet())
{
AddError(TEXT("Could not parse valid directlink source URI with SourceId"));
return false;
}
else if (!ParsedSourceDescription->SourceId.IsSet()
|| ParsedSourceDescription->SourceId.GetValue() != RandomGuid)
{
AddError(TEXT("Could not parse source id"));
return false;
}
}
{
const FSourceUri InvalidUriInvalidPath = FSourceUri(FDirectLinkUriResolver::GetDirectLinkScheme(), FString() / FString() / FString() / FString());
if (TOptional<FDirectLinkSourceDescription> ParsedSourceDescription = FDirectLinkUriResolver::TryParseDirectLinkUri(InvalidUriInvalidPath))
{
AddError(TEXT("DirectLink URI parsing did not fail on invalid path."));
return false;
}
const FSourceUri InvalidUriEmptyPath = FSourceUri(FDirectLinkUriResolver::GetDirectLinkScheme(), FString());
if (TOptional<FDirectLinkSourceDescription> ParsedSourceDescription = FDirectLinkUriResolver::TryParseDirectLinkUri(InvalidUriEmptyPath))
{
AddError(TEXT("DirectLink URI parsing did not fail on empty path."));
return false;
}
}
return true;
}
}