Integrating up through commit 90f050496
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Translation/TranslationSerializer.h>
|
||||
#include <Translation/TranslationAsset.h>
|
||||
|
||||
namespace GraphCanvas
|
||||
{
|
||||
namespace Schema
|
||||
{
|
||||
namespace Field
|
||||
{
|
||||
static constexpr char key[] = "key";
|
||||
static constexpr char context[] = "context";
|
||||
static constexpr char variant[] = "variant";
|
||||
static constexpr char entries[] = "entries";
|
||||
}
|
||||
|
||||
static const AZStd::string_view RequiredFields[] =
|
||||
{
|
||||
Field::key,
|
||||
Field::context,
|
||||
Field::variant,
|
||||
Field::entries
|
||||
};
|
||||
}
|
||||
|
||||
AZ_CLASS_ALLOCATOR_IMPL(TranslationFormatSerializer, AZ::SystemAllocator, 0);
|
||||
|
||||
void AddEntryToDatabase(const AZStd::string& baseKey, const AZStd::string& name, const rapidjson::Value& it, TranslationFormat* translationFormat)
|
||||
{
|
||||
AZStd::string finalKey = baseKey;
|
||||
if (it.IsString())
|
||||
{
|
||||
if (translationFormat->m_database.find(finalKey) == translationFormat->m_database.end())
|
||||
{
|
||||
translationFormat->m_database[finalKey] = it.GetString();
|
||||
}
|
||||
else
|
||||
{
|
||||
// There is a name collision
|
||||
AZStd::string error = AZStd::string::format("Unable to store key: %s with value: %s because that key already exists", finalKey.c_str(), it.GetString());
|
||||
AZ_Error("TranslationSerializer", false, error.c_str());
|
||||
}
|
||||
}
|
||||
else if (it.IsObject())
|
||||
{
|
||||
if (!name.empty())
|
||||
{
|
||||
finalKey.append(".");
|
||||
finalKey.append(name);
|
||||
}
|
||||
|
||||
AZStd::string itemKey = finalKey;
|
||||
for (auto objIt = it.MemberBegin(); objIt != it.MemberEnd(); ++objIt)
|
||||
{
|
||||
itemKey.append(".");
|
||||
itemKey.append(objIt->name.GetString());
|
||||
|
||||
AddEntryToDatabase(itemKey, name, objIt->value, translationFormat);
|
||||
|
||||
itemKey = finalKey;
|
||||
}
|
||||
|
||||
}
|
||||
else if (it.IsArray())
|
||||
{
|
||||
AZStd::string key = baseKey;
|
||||
if (!name.empty())
|
||||
{
|
||||
key.append(".");
|
||||
key.append(name);
|
||||
}
|
||||
|
||||
AZStd::string itemKey = key;
|
||||
|
||||
const rapidjson::Value& array = it;
|
||||
for (rapidjson::SizeType i = 0; i < array.Size(); ++i)
|
||||
{
|
||||
// so, here, I need to go in and if there is a "key" member within the object, then I need to use that,
|
||||
// if there isn't, I can use the %d
|
||||
if (array[i].IsObject())
|
||||
{
|
||||
if (array[i].HasMember(Schema::Field::key))
|
||||
{
|
||||
AZStd::string innerKey = array[i].FindMember(Schema::Field::key)->value.GetString();
|
||||
itemKey.append(AZStd::string::format(".%s", innerKey.c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
itemKey.append(AZStd::string::format(".%d", i));
|
||||
}
|
||||
}
|
||||
|
||||
AddEntryToDatabase(itemKey, "", array[i], translationFormat);
|
||||
|
||||
itemKey = key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AZ::JsonSerializationResult::Result TranslationFormatSerializer::Load(void* outputValue, const AZ::Uuid& outputValueTypeId,
|
||||
const rapidjson::Value& inputValue, AZ::JsonDeserializerContext& context)
|
||||
{
|
||||
AZ_Assert(azrtti_typeid<TranslationFormat>() == outputValueTypeId,
|
||||
"Unable to deserialize TranslationFormat to json because the provided type is %s",
|
||||
outputValueTypeId.ToString<AZStd::string>().c_str());
|
||||
AZ_UNUSED(outputValueTypeId);
|
||||
|
||||
TranslationFormat* translationFormat = reinterpret_cast<TranslationFormat*>(outputValue);
|
||||
AZ_Assert(translationFormat, "Output value for TranslationFormatSerializer can't be null.");
|
||||
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
JSR::ResultCode result(JSR::Tasks::ReadField);
|
||||
|
||||
if (!inputValue.IsObject())
|
||||
{
|
||||
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Translation data must be a JSON object.");
|
||||
}
|
||||
|
||||
if (!inputValue.HasMember(Schema::Field::entries) || !inputValue[Schema::Field::entries].IsArray())
|
||||
{
|
||||
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Translation data must be have a top level array of: entries");
|
||||
}
|
||||
|
||||
// Go over the entries
|
||||
{
|
||||
const rapidjson::Value::ConstMemberIterator entries = inputValue.FindMember(Schema::Field::entries);
|
||||
|
||||
rapidjson::SizeType entryCount = entries->value.Size();
|
||||
for (rapidjson::SizeType i = 0; i < entryCount; ++i)
|
||||
{
|
||||
const rapidjson::Value& entry = entries->value[i];
|
||||
|
||||
AZStd::string keyStr;
|
||||
rapidjson::Value::ConstMemberIterator keyValue;
|
||||
if (entry.HasMember(Schema::Field::key))
|
||||
{
|
||||
keyValue = entry.FindMember(Schema::Field::key);
|
||||
keyStr = keyValue->value.GetString();
|
||||
}
|
||||
|
||||
AZStd::string contextStr;
|
||||
rapidjson::Value::ConstMemberIterator contextValue;
|
||||
if (entry.HasMember(Schema::Field::context))
|
||||
{
|
||||
contextValue = entry.FindMember(Schema::Field::context);
|
||||
contextStr = contextValue->value.GetString();
|
||||
}
|
||||
|
||||
AZStd::string variantStr;
|
||||
rapidjson::Value::ConstMemberIterator variantValue;
|
||||
if (entry.HasMember(Schema::Field::variant))
|
||||
{
|
||||
variantValue = entry.FindMember(Schema::Field::variant);
|
||||
variantStr = variantValue->value.GetString();
|
||||
}
|
||||
|
||||
AZStd::string baseKey = contextStr;
|
||||
if (keyStr.empty())
|
||||
{
|
||||
AZ_Error("TranslationDatabase", false, "Every entry in the Translation data must have a key: %s", baseKey.c_str());
|
||||
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Every entry in the Translation data must have a key");
|
||||
}
|
||||
|
||||
if (!baseKey.empty())
|
||||
{
|
||||
baseKey.append(".");
|
||||
}
|
||||
|
||||
baseKey.append(keyStr);
|
||||
|
||||
if (!variantStr.empty())
|
||||
{
|
||||
baseKey.append(".");
|
||||
baseKey.append(variantStr);
|
||||
}
|
||||
|
||||
// Iterate over all members of entry
|
||||
for (auto it = entry.MemberBegin(); it != entry.MemberEnd(); ++it)
|
||||
{
|
||||
// Skip the fixed elements
|
||||
if (it == keyValue || it == contextValue || it == variantValue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
AddEntryToDatabase(baseKey, it->name.GetString(), it->value, translationFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Success, "Translation load success");
|
||||
}
|
||||
|
||||
AZ::JsonSerializationResult::Result TranslationFormatSerializer::Store(rapidjson::Value& /*outputValue*/, const void* /*inputValue*/,
|
||||
const void* /*defaultValue*/, const AZ::Uuid& /*valueTypeId*/, AZ::JsonSerializerContext& context)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::Unsupported, "Storing a Translation asset is not currently supported");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user