bool FJsonInternationalizationArchiveSerializer::DeserializeInternal(TSharedRef<FJsonObject> InJsonObj, TSharedRef<FInternationalizationArchive> InArchive, TSharedPtr<const FInternationalizationManifest> InManifest, TSharedPtr<const FInternationalizationArchive> InNativeArchive) { if (InJsonObj->HasField(TAG_FORMATVERSION)) { const int32 FormatVersion = static_cast<int32>(InJsonObj->GetNumberField(TAG_FORMATVERSION)); if (FormatVersion > (int32)FInternationalizationArchive::EFormatVersion::Latest) { // Archive is too new to be loaded! return false; } InArchive->SetFormatVersion(static_cast<FInternationalizationArchive::EFormatVersion>(FormatVersion)); } else { InArchive->SetFormatVersion(FInternationalizationArchive::EFormatVersion::Initial); } if (InArchive->GetFormatVersion() < FInternationalizationArchive::EFormatVersion::AddedKeys && !InManifest.IsValid()) { // Cannot load these archives without a manifest to key against return false; } if (JsonObjToArchive(InJsonObj, FString(), InArchive, InManifest, InNativeArchive)) { // We've been upgraded to the latest format now... InArchive->SetFormatVersion(FInternationalizationArchive::EFormatVersion::Latest); return true; } return false; }
bool FJsonInternationalizationArchiveSerializer::DeserializeInternal( TSharedRef< FJsonObject > InJsonObj, TSharedRef< FInternationalizationArchive > InternationalizationArchive ) { if( InJsonObj->HasField( TAG_FORMATVERSION ) ) { const int32 FormatVersion = static_cast<int>(InJsonObj->GetNumberField( TAG_FORMATVERSION )); InternationalizationArchive->SetFormatVersion(static_cast<FInternationalizationArchive::EFormatVersion>(FormatVersion)); } else { InternationalizationArchive->SetFormatVersion(FInternationalizationArchive::EFormatVersion::Initial); } return JsonObjToArchive( InJsonObj, TEXT(""), InternationalizationArchive ); }
bool FJsonInternationalizationArchiveSerializer::JsonObjToArchive(TSharedRef<FJsonObject> InJsonObj, const FString& ParentNamespace, TSharedRef<FInternationalizationArchive> InArchive, TSharedPtr<const FInternationalizationManifest> InManifest, TSharedPtr<const FInternationalizationArchive> InNativeArchive) { bool bConvertSuccess = true; FString AccumulatedNamespace = ParentNamespace; if (InJsonObj->HasField(TAG_NAMESPACE)) { if (!(AccumulatedNamespace.IsEmpty())) { AccumulatedNamespace += NAMESPACE_DELIMITER; } AccumulatedNamespace += InJsonObj->GetStringField(TAG_NAMESPACE); } else { UE_LOG(LogInternationalizationArchiveSerializer, Warning, TEXT("Encountered an object with a missing namespace while converting to Internationalization archive.")); bConvertSuccess = false; } // Process all the child objects if (bConvertSuccess && InJsonObj->HasField(TAG_CHILDREN)) { const TArray< TSharedPtr<FJsonValue> > ChildrenArray = InJsonObj->GetArrayField(TAG_CHILDREN); for (TArray< TSharedPtr< FJsonValue > >::TConstIterator ChildIter(ChildrenArray.CreateConstIterator()); ChildIter; ++ChildIter) { const TSharedPtr< FJsonValue > ChildEntry = *ChildIter; const TSharedPtr< FJsonObject > ChildJSONObject = ChildEntry->AsObject(); FString SourceText; TSharedPtr< FLocMetadataObject > SourceMetadata; if (ChildJSONObject->HasTypedField< EJson::String >(TAG_DEPRECATED_DEFAULTTEXT)) { SourceText = ChildJSONObject->GetStringField(TAG_DEPRECATED_DEFAULTTEXT); } else if (ChildJSONObject->HasTypedField< EJson::Object >(TAG_SOURCE)) { const TSharedPtr< FJsonObject > SourceJSONObject = ChildJSONObject->GetObjectField(TAG_SOURCE); if (SourceJSONObject->HasTypedField< EJson::String >(TAG_SOURCE_TEXT)) { SourceText = SourceJSONObject->GetStringField(TAG_SOURCE_TEXT); // Source meta data is mixed in with the source text, we'll process metadata if the source json object has more than one entry if (SourceJSONObject->Values.Num() > 1) { // We load in the entire source object as metadata and just remove the source text. FJsonInternationalizationMetaDataSerializer::DeserializeMetadata(SourceJSONObject.ToSharedRef(), SourceMetadata); if (SourceMetadata.IsValid()) { SourceMetadata->Values.Remove(TAG_SOURCE_TEXT); } } } else { bConvertSuccess = false; } } else { bConvertSuccess = false; } FString TranslationText; TSharedPtr< FLocMetadataObject > TranslationMetadata; if (ChildJSONObject->HasTypedField< EJson::String >(TAG_DEPRECATED_TRANSLATEDTEXT)) { TranslationText = ChildJSONObject->GetStringField(TAG_DEPRECATED_TRANSLATEDTEXT); } else if (ChildJSONObject->HasTypedField< EJson::Object >(TAG_TRANSLATION)) { const TSharedPtr< FJsonObject > TranslationJSONObject = ChildJSONObject->GetObjectField(TAG_TRANSLATION); if (TranslationJSONObject->HasTypedField< EJson::String >(TAG_TRANSLATION_TEXT)) { TranslationText = TranslationJSONObject->GetStringField(TAG_TRANSLATION_TEXT); // Source meta data is mixed in with the source text, we'll process metadata if the source json object has more than one entry if (TranslationJSONObject->Values.Num() > 1) { // We load in the entire source object as metadata and remove the source text FJsonInternationalizationMetaDataSerializer::DeserializeMetadata(TranslationJSONObject.ToSharedRef(), TranslationMetadata); if (TranslationJSONObject.IsValid()) { TranslationJSONObject->Values.Remove(TAG_TRANSLATION_TEXT); } } } else { bConvertSuccess = false; } } else { bConvertSuccess = false; } if (bConvertSuccess) { FLocItem Source(SourceText); Source.MetadataObj = SourceMetadata; FLocItem Translation(TranslationText); Translation.MetadataObj = TranslationMetadata; bool bIsOptional = false; if (ChildJSONObject->HasTypedField< EJson::Boolean >(TAG_OPTIONAL)) { bIsOptional = ChildJSONObject->GetBoolField(TAG_OPTIONAL); } TArray<FString> Keys; TSharedPtr< FLocMetadataObject > KeyMetadataNode; if (InArchive->GetFormatVersion() < FInternationalizationArchive::EFormatVersion::AddedKeys) { // We used to store the key meta-data as a top-level value, rather than within a "MetaData" object if (ChildJSONObject->HasTypedField< EJson::Object >(TAG_METADATA_KEY)) { const TSharedPtr< FJsonObject > MetaDataKeyJSONObject = ChildJSONObject->GetObjectField(TAG_METADATA_KEY); FJsonInternationalizationMetaDataSerializer::DeserializeMetadata(MetaDataKeyJSONObject.ToSharedRef(), KeyMetadataNode); } if (InManifest.IsValid()) { // We have no key in the archive data, so we must try and infer it from the manifest FLocTextHelper::FindKeysForLegacyTranslation(InManifest.ToSharedRef(), InNativeArchive, AccumulatedNamespace, SourceText, KeyMetadataNode, Keys); } } else { if (ChildJSONObject->HasTypedField< EJson::String >(TAG_KEY)) { Keys.Add(ChildJSONObject->GetStringField(TAG_KEY)); } if (ChildJSONObject->HasTypedField< EJson::Object >(TAG_METADATA)) { const TSharedPtr< FJsonObject > MetaDataJSONObject = ChildJSONObject->GetObjectField(TAG_METADATA); if (MetaDataJSONObject->HasTypedField< EJson::Object >(TAG_METADATA_KEY)) { const TSharedPtr< FJsonObject > MetaDataKeyJSONObject = MetaDataJSONObject->GetObjectField(TAG_METADATA_KEY); FJsonInternationalizationMetaDataSerializer::DeserializeMetadata(MetaDataKeyJSONObject.ToSharedRef(), KeyMetadataNode); } } } for (const FString& Key : Keys) { const bool bAddSuccessful = InArchive->AddEntry(AccumulatedNamespace, Key, Source, Translation, KeyMetadataNode, bIsOptional); if (!bAddSuccessful) { UE_LOG(LogInternationalizationArchiveSerializer, Warning, TEXT("Could not add JSON entry to the Internationalization archive: Namespace:%s Key:%s DefaultText:%s"), *AccumulatedNamespace, *Key, *SourceText); } } } } } if (bConvertSuccess && InJsonObj->HasField(TAG_SUBNAMESPACES)) { const TArray< TSharedPtr<FJsonValue> > SubnamespaceArray = InJsonObj->GetArrayField(TAG_SUBNAMESPACES); for (TArray< TSharedPtr< FJsonValue > >::TConstIterator SubnamespaceIter(SubnamespaceArray.CreateConstIterator()); SubnamespaceIter; ++SubnamespaceIter) { const TSharedPtr< FJsonValue > SubnamespaceEntry = *SubnamespaceIter; const TSharedPtr< FJsonObject > SubnamespaceJSONObject = SubnamespaceEntry->AsObject(); if (!JsonObjToArchive(SubnamespaceJSONObject.ToSharedRef(), AccumulatedNamespace, InArchive, InManifest, InNativeArchive)) { bConvertSuccess = false; break; } } } return bConvertSuccess; }
bool FInternationalizationArchiveJsonSerializer::JsonObjToArchive( TSharedRef< FJsonObject > InJsonObj, FString ParentNamespace, TSharedRef< FInternationalizationArchive > InternationalizationArchive ) { bool bConvertSuccess = true; FString AccumulatedNamespace = ParentNamespace; if( InJsonObj->HasField( TAG_NAMESPACE) ) { if( !( AccumulatedNamespace.IsEmpty() ) ) { AccumulatedNamespace += NAMESPACE_DELIMITER; } AccumulatedNamespace += InJsonObj->GetStringField( TAG_NAMESPACE ); } else { UE_LOG( LogInternationalizationArchiveSerializer, Warning,TEXT("Encountered an object with a missing namespace while converting to Internationalization archive.") ); bConvertSuccess = false; } // Process all the child objects if( bConvertSuccess && InJsonObj->HasField( TAG_CHILDREN ) ) { const TArray< TSharedPtr<FJsonValue> > ChildrenArray = InJsonObj->GetArrayField( TAG_CHILDREN ); for( TArray< TSharedPtr< FJsonValue > >::TConstIterator ChildIter( ChildrenArray.CreateConstIterator() ); ChildIter; ++ChildIter ) { const TSharedPtr< FJsonValue > ChildEntry = *ChildIter; const TSharedPtr< FJsonObject > ChildJSONObject = ChildEntry->AsObject(); FString SourceText; TSharedPtr< FLocMetadataObject > SourceMetadata; if( ChildJSONObject->HasTypedField< EJson::String >( TAG_DEPRECATED_DEFAULTTEXT ) ) { SourceText = ChildJSONObject->GetStringField( TAG_DEPRECATED_DEFAULTTEXT ); } else if( ChildJSONObject->HasTypedField< EJson::Object >( TAG_SOURCE ) ) { const TSharedPtr< FJsonObject > SourceJSONObject = ChildJSONObject->GetObjectField( TAG_SOURCE ); if( SourceJSONObject->HasTypedField< EJson::String >( TAG_SOURCE_TEXT ) ) { SourceText = SourceJSONObject->GetStringField( TAG_SOURCE_TEXT ); // Source meta data is mixed in with the source text, we'll process metadata if the source json object has more than one entry if( SourceJSONObject->Values.Num() > 1 ) { // We load in the entire source object as metadata and just remove the source text. FInternationalizationMetaDataJsonSerializer::DeserializeMetadata( SourceJSONObject.ToSharedRef(), SourceMetadata ); if( SourceMetadata.IsValid() ) { SourceMetadata->Values.Remove( TAG_SOURCE_TEXT ); } } } else { bConvertSuccess = false; } } else { bConvertSuccess = false; } FString TranslationText; TSharedPtr< FLocMetadataObject > TranslationMetadata; if( ChildJSONObject->HasTypedField< EJson::String >( TAG_DEPRECATED_TRANSLATEDTEXT ) ) { TranslationText = ChildJSONObject->GetStringField( TAG_DEPRECATED_TRANSLATEDTEXT ); } else if( ChildJSONObject->HasTypedField< EJson::Object >( TAG_TRANSLATION ) ) { const TSharedPtr< FJsonObject > TranslationJSONObject = ChildJSONObject->GetObjectField( TAG_TRANSLATION ); if( TranslationJSONObject->HasTypedField< EJson::String >( TAG_TRANSLATION_TEXT ) ) { TranslationText = TranslationJSONObject->GetStringField( TAG_TRANSLATION_TEXT ); // Source meta data is mixed in with the source text, we'll process metadata if the source json object has more than one entry if( TranslationJSONObject->Values.Num() > 1 ) { // We load in the entire source object as metadata and remove the source text FInternationalizationMetaDataJsonSerializer::DeserializeMetadata( TranslationJSONObject.ToSharedRef(), TranslationMetadata ); if( TranslationJSONObject.IsValid() ) { TranslationJSONObject->Values.Remove( TAG_TRANSLATION_TEXT ); } } } else { bConvertSuccess = false; } } else { bConvertSuccess = false; } if( bConvertSuccess ) { FLocItem Source( SourceText ); Source.MetadataObj = SourceMetadata; FLocItem Translation( TranslationText ); Translation.MetadataObj = TranslationMetadata; bool bIsOptional = false; if( ChildJSONObject->HasTypedField< EJson::Boolean >( TAG_OPTIONAL ) ) { bIsOptional = ChildJSONObject->GetBoolField( TAG_OPTIONAL ); } TSharedPtr< FLocMetadataObject > MetadataNode; if( ChildJSONObject->HasTypedField< EJson::Object >( TAG_METADATA_KEY ) ) { const TSharedPtr< FJsonObject > MetaDataKeyJSONObject = ChildJSONObject->GetObjectField( TAG_METADATA_KEY ); FInternationalizationMetaDataJsonSerializer::DeserializeMetadata( MetaDataKeyJSONObject.ToSharedRef(), MetadataNode ); } bool bAddSuccessful = InternationalizationArchive->AddEntry( AccumulatedNamespace, Source, Translation, MetadataNode, bIsOptional ); if( !bAddSuccessful ) { UE_LOG( LogInternationalizationArchiveSerializer, Warning,TEXT("Could not add JSON entry to the Internationalization archive: Namespace:%s DefaultText:%s"), *AccumulatedNamespace, *SourceText ); } } } } if( bConvertSuccess && InJsonObj->HasField( TAG_SUBNAMESPACES ) ) { const TArray< TSharedPtr<FJsonValue> > SubnamespaceArray = InJsonObj->GetArrayField( TAG_SUBNAMESPACES ); for(TArray< TSharedPtr< FJsonValue > >::TConstIterator SubnamespaceIter( SubnamespaceArray.CreateConstIterator() ); SubnamespaceIter; ++SubnamespaceIter ) { const TSharedPtr< FJsonValue > SubnamespaceEntry = *SubnamespaceIter; const TSharedPtr< FJsonObject > SubnamespaceJSONObject = SubnamespaceEntry->AsObject(); if( !JsonObjToArchive( SubnamespaceJSONObject.ToSharedRef(), AccumulatedNamespace, InternationalizationArchive ) ) { bConvertSuccess = false; break; } } } return bConvertSuccess; }
bool FInternationalizationArchiveJsonSerializer::DeserializeInternal( TSharedRef< FJsonObject > InJsonObj, TSharedRef< FInternationalizationArchive > InternationalizationArchive ) { return JsonObjToArchive( InJsonObj, TEXT(""), InternationalizationArchive ); }