TSharedPtr< FSurveyPage > FSurveyPage::Create( const TSharedRef< class FEpicSurvey >& InEpicSurvey, const TSharedRef< FJsonObject >& JsonObject ) { TSharedPtr< FSurveyPage > Page = MakeShareable( new FSurveyPage( InEpicSurvey ) ); if( JsonObject->HasTypedField< EJson::Array >( "blocks" ) ) { TArray< TSharedPtr< FJsonValue > > JsonSurveyBlocks = JsonObject->GetArrayField( "blocks" ); for (int Index = 0; Index < JsonSurveyBlocks.Num(); Index++) { TSharedPtr< FQuestionBlock > Block = FQuestionBlock::Create( InEpicSurvey, JsonSurveyBlocks[Index]->AsObject().ToSharedRef() ); if ( Block.IsValid() ) { Page->Blocks.Add( Block.ToSharedRef() ); } } } return Page; }
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; }
TSharedPtr< FQuestionBlock > FQuestionBlock::Create( const TSharedRef< class FEpicSurvey >& InEpicSurvey, const TSharedRef< FJsonObject >& JsonConfig ) { TSharedPtr< FQuestionBlock > Block = MakeShareable( new FQuestionBlock( InEpicSurvey ) ); Block->Style = Style_Inline; if ( JsonConfig->HasTypedField< EJson::String >( TEXT("style") ) ) { const FString Style = JsonConfig->GetStringField( TEXT("style") ); if ( Style == TEXT("multiline") ) { Block->Style = Style_Multiline; } else if ( Style == TEXT("multiline-text") ) { Block->Style = Style_MultilineText; } else if ( Style == TEXT("inline-text") ) { Block->Style = Style_InlineText; } else if ( Style == TEXT("columns") ) { Block->Style = Style_Columns; } } Block->Instructions = FText::GetEmpty(); if ( JsonConfig->HasTypedField< EJson::String >( TEXT("instructions") ) ) { Block->Instructions = FText::FromString( JsonConfig->GetStringField( TEXT("instructions") ) ); } Block->bIsRequired = true; if ( JsonConfig->HasTypedField< EJson::Boolean >( TEXT("required") ) ) { Block->bIsRequired = JsonConfig->GetBoolField( TEXT("required") ); } Block->Response = FQuestionBlock::Response_Single; if ( JsonConfig->HasTypedField< EJson::String >( TEXT("response") ) ) { const FString ResponseString = JsonConfig->GetStringField( TEXT("response") ); if ( ResponseString == TEXT("multi") ) { Block->Response = FQuestionBlock::Response_Multi; } } else if ( JsonConfig->HasTypedField< EJson::Number >( TEXT("response") ) ) { int32 ResponseNumber = (int32)( JsonConfig->GetNumberField( TEXT("response") ) ); if ( ResponseNumber <= 0 ) { Block->Response = FQuestionBlock::Response_Multi; } else if ( ResponseNumber == 1 ) { Block->Response = FQuestionBlock::Response_Multi; } else { Block->Response = (FQuestionBlock::EResponse)ResponseNumber; } } if ( JsonConfig->HasTypedField< EJson::Array >( TEXT("questions") ) ) { TArray< TSharedPtr< FJsonValue > > QuestionStrings = JsonConfig->GetArrayField( TEXT("questions") ); for (int Index = 0; Index < QuestionStrings.Num(); Index++) { const FString Question = QuestionStrings[Index]->AsString(); if ( !Question.IsEmpty() ) { Block->Questions.Add( FText::FromString( Question ) ); Block->UserAnswers.Add( TArray< int32 >() ); Block->UserTextAnswers.Add( TArray< FString >() ); } } } if ( JsonConfig->HasTypedField< EJson::Array >( TEXT("answers") ) ) { TArray< TSharedPtr< FJsonValue > > AnswerStrings = JsonConfig->GetArrayField( TEXT("answers") ); for (int AnswerIndex = 0; AnswerIndex < AnswerStrings.Num(); AnswerIndex++) { for (int QuestionIndex = 0; QuestionIndex < Block->UserTextAnswers.Num(); QuestionIndex++) { Block->UserTextAnswers[QuestionIndex].Push( FString() ); } FAnswer Answer; switch( AnswerStrings[AnswerIndex]->Type ) { case EJson::String: { Answer.Text = FText::FromString( AnswerStrings[AnswerIndex]->AsString() ); } break; case EJson::Object: { TSharedPtr<FJsonObject> SubObject = AnswerStrings[AnswerIndex]->AsObject(); if( SubObject.IsValid() ) { if( SubObject->HasTypedField< EJson::String >( TEXT("text") ) ) { Answer.Text = FText::FromString( SubObject->GetStringField( TEXT("text") ) ); } if( SubObject->HasTypedField< EJson::Array >( TEXT("branch_points") ) ) { TArray< TSharedPtr< FJsonValue > > BranchPointsArray = SubObject->GetArrayField( TEXT("branch_points") ); for (int BranchIndex = 0; BranchIndex < BranchPointsArray.Num(); ++BranchIndex) { TSharedPtr<FJsonObject> BranchObject = BranchPointsArray[BranchIndex]->AsObject(); if( BranchObject.IsValid() ) { FString BranchName; int32 BranchPoints = 0; if( BranchObject->HasTypedField< EJson::String >("branch") ) { BranchName = BranchObject->GetStringField("branch"); } if( BranchObject->HasTypedField< EJson::Number >("points") ) { BranchPoints = int32(BranchObject->GetNumberField("points")); } if( !BranchName.IsEmpty() && (BranchPoints > 0) ) { Answer.Branches.Add( BranchName, BranchPoints ); } } } } } } break; } Block->Answers.Add( Answer ); } } return Block; }
TSharedPtr< FSurvey > FSurvey::Create( const TSharedRef< class FEpicSurvey >& InEpicSurvey, const TSharedRef< FJsonObject >& JsonConfig ) { FGuid Identifier; if (!FGuid::ParseExact(JsonConfig->GetStringField( TEXT("id") ), EGuidFormats::DigitsWithHyphens, Identifier)) { return nullptr; } TSharedPtr< FSurvey > NewSurvey( new FSurvey( InEpicSurvey ) ); NewSurvey->Identifier = Identifier; NewSurvey->BannerBrushPath = JsonConfig->GetStringField( TEXT("banner") ); NewSurvey->DisplayName = FText::FromString( JsonConfig->GetStringField( TEXT("name") ) ); NewSurvey->Instructions = FText::FromString( JsonConfig->GetStringField( TEXT("instructions") ) ); NewSurvey->SurveyType = ESurveyType::Normal; NewSurvey->AutoPrompt = true; NewSurvey->SurveyVersion = 1; NewSurvey->MinEngineVersion.Empty(); NewSurvey->MaxEngineVersion.Empty(); if ( JsonConfig->HasTypedField<EJson::Boolean>( TEXT("auto_prompt") ) ) { NewSurvey->AutoPrompt = int32(JsonConfig->GetBoolField( TEXT("auto_prompt") ) ); } if( JsonConfig->HasTypedField<EJson::Number>( TEXT("survey_version") ) ) { NewSurvey->SurveyVersion = int32(JsonConfig->GetNumberField( TEXT("survey_version") ) ); } if( JsonConfig->HasTypedField<EJson::String>( TEXT("min_engine_version") ) ) { FEngineVersion::Parse( JsonConfig->GetStringField( TEXT("min_engine_version") ), NewSurvey->MinEngineVersion ); } if (JsonConfig->HasTypedField<EJson::String>(TEXT("max_engine_version"))) { FEngineVersion::Parse( JsonConfig->GetStringField( TEXT("max_engine_version") ), NewSurvey->MaxEngineVersion ); } if( (NewSurvey->SurveyVersion != CurrentSurveyVersion) || (!NewSurvey->MinEngineVersion.IsEmpty() && GEngineVersion.IsCompatibleWith(NewSurvey->MinEngineVersion)) || (!NewSurvey->MaxEngineVersion.IsEmpty() && NewSurvey->MaxEngineVersion.IsCompatibleWith(GEngineVersion)) ) { return NULL; } if( JsonConfig->HasTypedField<EJson::String>( "type" ) ) { FString SurveyType = JsonConfig->GetStringField( TEXT("type") ); if( !SurveyType.IsEmpty() ) { if( SurveyType == TEXT( "branch" ) ) { NewSurvey->SurveyType = ESurveyType::Branch; } } } if( JsonConfig->HasTypedField< EJson::Array >( "branches" ) ) { TArray< TSharedPtr< FJsonValue > > JsonSurveyBranches = JsonConfig->GetArrayField( "branches" ); for (int Index = 0; Index < JsonSurveyBranches.Num(); Index++) { TSharedPtr< FSurveyBranch > Branch = FSurveyBranch::Create( InEpicSurvey, JsonSurveyBranches[Index]->AsObject().ToSharedRef() ); if ( Branch.IsValid() ) { NewSurvey->Branches.Add( Branch.ToSharedRef() ); InEpicSurvey->AddBranch( Branch->GetBranchName() ); } } } if( JsonConfig->HasTypedField< EJson::Array >( "pages" ) ) { TArray< TSharedPtr< FJsonValue > > JsonSurveyPages = JsonConfig->GetArrayField( "pages" ); for (int Index = 0; Index < JsonSurveyPages.Num(); Index++) { TSharedPtr< FJsonObject > PageObject = JsonSurveyPages[Index]->AsObject(); if( PageObject.IsValid() ) { TSharedPtr<FSurveyPage> Page = FSurveyPage::Create( InEpicSurvey, PageObject.ToSharedRef() ); if( Page.IsValid() ) { NewSurvey->Pages.Add( Page.ToSharedRef() ); if( NewSurvey->SurveyType == ESurveyType::Branch ) { Page->SetBranchSurvey( NewSurvey ); } } } } } else { TSharedPtr<FSurveyPage> Page = FSurveyPage::Create( InEpicSurvey, JsonConfig ); if( Page.IsValid() ) { NewSurvey->Pages.Add( Page.ToSharedRef() ); } } return NewSurvey; }
bool FInternationalizationManifestJsonSerializer::JsonObjToManifest( TSharedRef< FJsonObject > InJsonObj, FString ParentNamespace, TSharedRef< FInternationalizationManifest > Manifest ) { bool bConvertSuccess = true; FString AccumulatedNamespace = ParentNamespace; if( InJsonObj->HasField( TAG_NAMESPACE) ) { if( !( AccumulatedNamespace.IsEmpty() ) ) { AccumulatedNamespace += NAMESPACE_DELIMITER; } AccumulatedNamespace += InJsonObj->GetStringField( TAG_NAMESPACE ); } else { // We found an entry with a missing namespace 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 && bConvertSuccess; ++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 remove the source object FInternationalizationMetaDataJsonSerializer::DeserializeMetadata( SourceJSONObject.ToSharedRef(), SourceMetadata ); if( SourceMetadata.IsValid() ) { SourceMetadata->Values.Remove( TAG_SOURCE_TEXT ); } } } else { bConvertSuccess = false; } } else { bConvertSuccess = false; } FLocItem Source(SourceText); Source.MetadataObj = SourceMetadata; if( bConvertSuccess && ChildJSONObject->HasField( TAG_KEYCOLLECTION ) ) { const TArray< TSharedPtr<FJsonValue> > ContextArray = ChildJSONObject->GetArrayField( TAG_KEYCOLLECTION); for(TArray< TSharedPtr< FJsonValue > >::TConstIterator ContextIter( ContextArray.CreateConstIterator() ); ContextIter && bConvertSuccess; ++ContextIter) { const TSharedPtr< FJsonValue > ContextEntry = *ContextIter; const TSharedPtr< FJsonObject > ContextJSONObject = ContextEntry->AsObject(); if( ContextJSONObject->HasTypedField< EJson::String >( TAG_KEY ) ) { const FString Key = ContextJSONObject->GetStringField( TAG_KEY ); const FString SourceLocation = ContextJSONObject->HasField( TAG_PATH ) ? ContextJSONObject->GetStringField( TAG_PATH ) : FString(); FContext CommandContext; CommandContext.Key = Key; CommandContext.SourceLocation = SourceLocation; if( ContextJSONObject->HasTypedField< EJson::Boolean >( TAG_OPTIONAL ) ) { CommandContext.bIsOptional = ContextJSONObject->GetBoolField( TAG_OPTIONAL ); } if( ContextJSONObject->HasTypedField< EJson::Object >( TAG_METADATA ) ) { const TSharedPtr< FJsonObject > MetaDataJSONObject = ContextJSONObject->GetObjectField( TAG_METADATA ); if( MetaDataJSONObject->HasTypedField< EJson::Object >( TAG_METADATA_INFO ) ) { const TSharedPtr< FJsonObject > MetaDataInfoJSONObject = MetaDataJSONObject->GetObjectField( TAG_METADATA_INFO ); TSharedPtr< FLocMetadataObject > MetadataNode; FInternationalizationMetaDataJsonSerializer::DeserializeMetadata( MetaDataInfoJSONObject.ToSharedRef(), MetadataNode ); if( MetadataNode.IsValid() ) { CommandContext.InfoMetadataObj = MetadataNode; } } if( MetaDataJSONObject->HasTypedField< EJson::Object >( TAG_METADATA_KEY ) ) { const TSharedPtr< FJsonObject > MetaDataKeyJSONObject = MetaDataJSONObject->GetObjectField( TAG_METADATA_KEY ); TSharedPtr< FLocMetadataObject > MetadataNode; FInternationalizationMetaDataJsonSerializer::DeserializeMetadata( MetaDataKeyJSONObject.ToSharedRef(), MetadataNode ); if( MetadataNode.IsValid() ) { CommandContext.KeyMetadataObj = MetadataNode; } } } bool bAddSuccessful = Manifest->AddSource( AccumulatedNamespace, Source, CommandContext ); if(!bAddSuccessful) { UE_LOG( LogInternationalizationManifestSerializer, Warning,TEXT("Could not add JSON entry to the Internationalization manifest: Namespace:%s SourceText:%s SourceData:%s"), *AccumulatedNamespace, *SourceText, *FInternationalizationMetaDataJsonSerializer::MetadataToString(Source.MetadataObj) ); } } else { //We found a context entry that is missing a identifier/key or a path bConvertSuccess = false; break; } } } else { // We have an entry that is missing a key/context collection or default text entry. bConvertSuccess = false; break; } } } 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( !JsonObjToManifest( SubnamespaceJSONObject.ToSharedRef(), AccumulatedNamespace, Manifest ) ) { 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; }