TMService { public String generateLocalized( Asset asset, String content, RepositoryLocale repositoryLocale, String outputBcp47tag, FilterConfigIdOverride filterConfigIdOverride, List<String> filterOptions, Status status, InheritanceMode inheritanceMode) throws UnsupportedAssetFilterTypeException { String bcp47Tag; if (outputBcp47tag == null) { bcp47Tag = repositoryLocale.getLocale().getBcp47Tag(); } else { logger.debug("An output bcp47 tag: {} is specified (won't use the default tag (from the repository locale)", outputBcp47tag); bcp47Tag = outputBcp47tag; } logger.debug("Configuring pipeline for localized XLIFF generation"); BasePipelineStep translateStep = (BasePipelineStep) new TranslateStep(asset, repositoryLocale, inheritanceMode, status); return generateLocalizedBase(asset, content, filterConfigIdOverride, filterOptions, translateStep, bcp47Tag); }  TMTextUnit addTMTextUnit(Long tmId, Long assetId, String name, String content, String comment); TMTextUnit addTMTextUnit(
            TM tm,
            Asset asset,
            String name,
            String content,
            String comment,
            DateTime createdDate,
            PluralForm pluralForm,
            String pluralFormOther); TMTextUnit addTMTextUnit(
            TM tm,
            Asset asset,
            String name,
            String content,
            String comment,
            User createdByUser,
            DateTime createdDate,
            PluralForm pluralForm,
            String pluralFormOther); TMTextUnitVariant addCurrentTMTextUnitVariant(Long tmTextUnitId, Long localeId, String content); TMTextUnitVariant addCurrentTMTextUnitVariant(Long tmTextUnitId, Long localeId, String content, TMTextUnitVariant.Status status, boolean includedInLocalizedFile); TMTextUnitVariant addCurrentTMTextUnitVariant(Long tmTextUnitId, Long localeId, String content, TMTextUnitVariant.Status status, boolean includedInLocalizedFile, DateTime createdDate); TMTextUnitCurrentVariant addTMTextUnitCurrentVariant(Long tmTextUnitId, Long localeId, String content, String comment); TMTextUnitCurrentVariant addTMTextUnitCurrentVariant(Long tmTextUnitId, Long localeId, String content, String comment, TMTextUnitVariant.Status status); TMTextUnitCurrentVariant addTMTextUnitCurrentVariant(
            Long tmTextUnitId,
            Long localeId,
            String content,
            String comment,
            TMTextUnitVariant.Status status,
            boolean includedInLocalizedFile); TMTextUnitCurrentVariant addTMTextUnitCurrentVariant(
            Long tmTextUnitId,
            Long localeId,
            String content,
            String comment,
            TMTextUnitVariant.Status status,
            boolean includedInLocalizedFile,
            DateTime createdDate); AddTMTextUnitCurrentVariantResult addTMTextUnitCurrentVariantWithResult(
            Long tmTextUnitId,
            Long localeId,
            String content,
            String comment,
            TMTextUnitVariant.Status status,
            boolean includedInLocalizedFile,
            DateTime createdDate); AddTMTextUnitCurrentVariantResult addTMTextUnitCurrentVariantWithResult(
            TMTextUnitCurrentVariant tmTextUnitCurrentVariant,
            Long tmId,
            Long tmTextUnitId,
            Long localeId,
            String content,
            String comment,
            TMTextUnitVariant.Status status,
            boolean includedInLocalizedFile,
            DateTime createdDate,
            User createdBy); boolean isUpdateNeededForTmTextUnitVariant(
            TMTextUnitVariant.Status currentStatus,
            String currentContentMd5,
            boolean currentIncludedInLocalizedFile,
            String currentComment,
            TMTextUnitVariant.Status newStatus,
            String newContentMd5,
            boolean newIncludedInLocalizedFile,
            String newComment); TMTextUnitVariant addTMTextUnitVariant(
            Long tmTextUnitId,
            Long localeId,
            String content,
            String comment,
            TMTextUnitVariant.Status status,
            boolean includedInLocalizedFile,
            DateTime createdDate); TMTextUnitVariant addTMTextUnitVariant(
            Long tmTextUnitId,
            Long localeId,
            String content,
            String comment,
            TMTextUnitVariant.Status status,
            boolean includedInLocalizedFile,
            DateTime createdDate,
            User createdBy); UpdateTMWithXLIFFResult updateTMWithTranslationKitXLIFF(
            String xliffContent,
            TMTextUnitVariant.Status importStatus,
            String dropImporterUsernameOverride); UpdateTMWithXLIFFResult updateTMWithXLIFFById(
            String xliffContent,
            TMTextUnitVariant.Status importStatus); UpdateTMWithXLIFFResult updateTMWithXLIFFByMd5(
            String xliffContent,
            TMTextUnitVariant.Status importStatus,
            Repository repository); @Transactional String exportAssetAsXLIFF(Long assetId, String bcp47Tag); String generateLocalized(
            Asset asset,
            String content,
            RepositoryLocale repositoryLocale,
            String outputBcp47tag,
            FilterConfigIdOverride filterConfigIdOverride,
            List<String> filterOptions,
            Status status,
            InheritanceMode inheritanceMode); String generatePseudoLocalized(
            Asset asset,
            String content,
            FilterConfigIdOverride filterConfigIdOverride); PollableFuture<Void> importLocalizedAssetAsync(
            Long assetId,
            String content,
            Long localeId,
            StatusForEqualTarget statusForEqualtarget,
            FilterConfigIdOverride filterConfigIdOverride,
            List<String> filterOptions); void importLocalizedAsset(
            Long assetId,
            String content,
            Long localeId,
            StatusForEqualTarget statusForEqualtarget,
            FilterConfigIdOverride filterConfigIdOverride,
            List<String> filterOptions); @Pollable(async = true, message = "Export asset as xliff") PollableFuture<String> exportAssetAsXLIFFAsync(
            Long tmXliffId,
            Long assetId,
            String bcp47Tag,
            @InjectCurrentTask PollableTask currentTask); TMXliff createTMXliff(Long assetId, String bcp47Tag, String content, PollableTask pollableTask);  }
@Test public void testLocalizeAndroidStringsWithSpecialCharactersOldEscaping() throws Exception { List<String> filterOptionOldEscaping = Arrays.asList("oldEscaping=true"); Repository repo = repositoryService.createRepository(testIdWatcher.getEntityName("repository")); RepositoryLocale repoLocale; try { repoLocale = repositoryService.addRepositoryLocale(repo, "en-GB"); } catch (RepositoryLocaleCreationException e) { throw new RuntimeException(e); } String assetContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<resources>\n" + " <string description=\"Example html markup string1\" name=\"welcome1\">Welcome to <b>Android</b>!</string>\n" + " <string description=\"Example html markup string2\" name=\"welcome2\">Welcome to <i>Android</i>!</string>\n" + " <string description=\"Example html markup string3\" name=\"welcome3\">Welcome to <u>Android</u>!</string>\n" + " <string description=\"Example html markup string4\" name=\"welcome4\">Welcome to <annotation font=\"title_emphasis\">Android</annotation>!</string>\n" + " <string name=\"subheader_text1\">\\\'Make sure you\\\'d \\\"escaped\\\" special characters like quotes &amp; ampersands.\\n</string>\n" + " <string name=\"subheader_text2\">\"This'll also work\"</string>\n" + "</resources>"; asset = assetService.createAssetWithContent(repo.getId(), "res/values/strings.xml", assetContent); asset = assetRepository.findById(asset.getId()).orElse(null); assetId = asset.getId(); tmId = repo.getTm().getId(); PollableFuture<Asset> assetResult = assetService.addOrUpdateAssetAndProcessIfNeeded(repo.getId(), asset.getPath(), assetContent, false, null, null, null, filterOptionOldEscaping); try { pollableTaskService.waitForPollableTask(assetResult.getPollableTask().getId()); } catch (PollableTaskException | InterruptedException e) { throw new RuntimeException(e); } assetResult.get(); TextUnitSearcherParameters textUnitSearcherParameters = new TextUnitSearcherParameters(); textUnitSearcherParameters.setRepositoryIds(repo.getId()); textUnitSearcherParameters.setStatusFilter(StatusFilter.FOR_TRANSLATION); List<TextUnitDTO> textUnitDTOs = textUnitSearcher.search(textUnitSearcherParameters); for (TextUnitDTO textUnitDTO : textUnitDTOs) { logger.debug("source=[{}]", textUnitDTO.getSource()); } String localizedAsset = tmService.generateLocalized(asset, assetContent, repoLocale, "en-GB", null, filterOptionOldEscaping, Status.ALL, InheritanceMode.USE_PARENT); logger.debug("localized=\n{}", localizedAsset); assertEquals(assetContent, localizedAsset); }
@Test public void testLocalizeAndroidStringsWithSpecialCharacters() throws Exception { Repository repo = repositoryService.createRepository(testIdWatcher.getEntityName("repository")); RepositoryLocale repoLocale; try { repoLocale = repositoryService.addRepositoryLocale(repo, "en-GB"); } catch (RepositoryLocaleCreationException e) { throw new RuntimeException(e); } String assetContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<resources>\n" + " <string description=\"Example html markup string1\" name=\"welcome1\">Welcome to <b>Android</b>!</string>\n" + " <string description=\"Example html markup string2\" name=\"welcome2\">Welcome to <i>Android</i>!</string>\n" + " <string description=\"Example html markup string3\" name=\"welcome3\">Welcome to <u>Android</u>!</string>\n" + " <string name=\"subheader_text1\">\\\'Make sure you\\\'d \\\"escaped\\\" special characters like quotes &amp; ampersands.\\n</string>\n" + " <string name=\"subheader_text2\">\"This'll also work\"</string>\n" + " <string name=\"escape_dot\">\\.</string>\n" + " <string name=\"escape_quote\">\\'</string>\n" + " <string name=\"escape_apostrophe\">\\ʼ</string>\n" + " <string name=\"escape_escape\">\\\\</string>\n" + " <string name=\"escape_at_sign\">\\@</string>\n" + " <string name=\"escape_ampersand\">&amp;</string>\n" + " <string name=\"escape_lowerthan\">&lt;</string>\n" + " <string name=\"replace_tab\">a\tb\tc</string>\n" + " <string name=\"remove_line_feed\">\nline1\n line2\n line3 </string>\n" + " <string name=\"escape_line_feed2\">\\nline1\\n line2\\n line3 </string>\n" + " <string name=\"trim\"> \n a \n </string>\n" + "</resources>"; asset = assetService.createAssetWithContent(repo.getId(), "res/values/strings.xml", assetContent); asset = assetRepository.findById(asset.getId()).orElse(null); assetId = asset.getId(); tmId = repo.getTm().getId(); PollableFuture<Asset> assetResult = assetService.addOrUpdateAssetAndProcessIfNeeded(repo.getId(), asset.getPath(), assetContent, false, null, null, null, null); try { pollableTaskService.waitForPollableTask(assetResult.getPollableTask().getId()); } catch (PollableTaskException | InterruptedException e) { throw new RuntimeException(e); } assetResult.get(); TextUnitSearcherParameters textUnitSearcherParameters = new TextUnitSearcherParameters(); textUnitSearcherParameters.setRepositoryIds(repo.getId()); textUnitSearcherParameters.setStatusFilter(StatusFilter.FOR_TRANSLATION); List<TextUnitDTO> textUnitDTOs = textUnitSearcher.search(textUnitSearcherParameters); for (TextUnitDTO textUnitDTO : textUnitDTOs) { logger.debug("source=[{}]", textUnitDTO.getSource()); } String localizedAsset = tmService.generateLocalized(asset, assetContent, repoLocale, "en-GB", null, null, Status.ALL, InheritanceMode.USE_PARENT); logger.debug("localized=\n{}", localizedAsset); String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<resources>\n" + " <string description=\"Example html markup string1\" name=\"welcome1\">Welcome to <b>Android</b>!</string>\n" + " <string description=\"Example html markup string2\" name=\"welcome2\">Welcome to <i>Android</i>!</string>\n" + " <string description=\"Example html markup string3\" name=\"welcome3\">Welcome to <u>Android</u>!</string>\n" + " <string name=\"subheader_text1\">\\'Make sure you\\'d \\\"escaped\\\" special characters like quotes &amp; ampersands.\\n</string>\n" + " <string name=\"subheader_text2\">This\\'ll also work</string>\n" + " <string name=\"escape_dot\">.</string>\n" + " <string name=\"escape_quote\">\\'</string>\n" + " <string name=\"escape_apostrophe\">ʼ</string>\n" + " <string name=\"escape_escape\">\\</string>\n" + " <string name=\"escape_at_sign\">@</string>\n" + " <string name=\"escape_ampersand\">&amp;</string>\n" + " <string name=\"escape_lowerthan\">&lt;</string>\n" + " <string name=\"replace_tab\">a b c</string>\n" + " <string name=\"remove_line_feed\">line1 line2 line3</string>\n" + " <string name=\"escape_line_feed2\">\\nline1\\n line2\\n line3</string>\n" + " <string name=\"trim\">a</string>\n" + "</resources>"; assertEquals(expected, localizedAsset); }
@Test public void testLocalizeAndroidStringsWithEscapedHTMLAndCDATA() throws Exception { Repository repo = repositoryService.createRepository(testIdWatcher.getEntityName("repository")); RepositoryLocale repoLocale; try { repoLocale = repositoryService.addRepositoryLocale(repo, "en-GB"); } catch (RepositoryLocaleCreationException e) { throw new RuntimeException(e); } String assetContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<resources>\n" + " <string name=\"welcome_messages0\">Hello, %1$s! You have <b>%2$d new messages</b>.</string>\n" + " <string name=\"welcome_messages1\">Hello, %1$s! You have &lt;b>%2$d new messages&lt;/b>.</string>\n" + " <string name=\"welcome_messages2\">Hello, %1$s! You have <![CDATA[<b>%2$d new messages</b>]]>.</string>\n" + "</resources>"; String expectedLocalizedAsset = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<resources>\n" + " <string name=\"welcome_messages0\">Hello, %1$s! You have &lt;b>%2$d new messages&lt;/b>.</string>\n" + " <string name=\"welcome_messages1\">Hello, %1$s! You have &lt;b>%2$d new messages&lt;/b>.</string>\n" + " <string name=\"welcome_messages2\">Hello, %1$s! You have &lt;b>%2$d new messages&lt;/b>.</string>\n" + "</resources>"; asset = assetService.createAssetWithContent(repo.getId(), "res/values/strings.xml", assetContent); asset = assetRepository.findById(asset.getId()).orElse(null); assetId = asset.getId(); tmId = repo.getTm().getId(); PollableFuture<Asset> assetResult = assetService.addOrUpdateAssetAndProcessIfNeeded(repo.getId(), asset.getPath(), assetContent, false, null, null, null, null); try { pollableTaskService.waitForPollableTask(assetResult.getPollableTask().getId()); } catch (PollableTaskException | InterruptedException e) { throw new RuntimeException(e); } assetResult.get(); TextUnitSearcherParameters textUnitSearcherParameters = new TextUnitSearcherParameters(); textUnitSearcherParameters.setRepositoryIds(repo.getId()); textUnitSearcherParameters.setStatusFilter(StatusFilter.FOR_TRANSLATION); List<TextUnitDTO> textUnitDTOs = textUnitSearcher.search(textUnitSearcherParameters); for (TextUnitDTO textUnitDTO : textUnitDTOs) { logger.debug("source=[{}]", textUnitDTO.getSource()); assertEquals("Hello, %1$s! You have <b>%2$d new messages</b>.", textUnitDTO.getSource()); } String localizedAsset = tmService.generateLocalized(asset, assetContent, repoLocale, "en-GB", null, null, Status.ALL, InheritanceMode.USE_PARENT); logger.debug("localized=\n{}", localizedAsset); assertEquals(expectedLocalizedAsset, localizedAsset); }
@Test public void testLocalizeAndroidStringsPlural() throws Exception { Repository repo = repositoryService.createRepository(testIdWatcher.getEntityName("repository")); RepositoryLocale repoLocale; try { repoLocale = repositoryService.addRepositoryLocale(repo, "ja-JP"); repoLocale = repositoryService.addRepositoryLocale(repo, "en-GB"); } catch (RepositoryLocaleCreationException e) { throw new RuntimeException(e); } String assetContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<resources>\n" + " <!-- Example of plurals -->\n" + " <plurals name=\"numberOfCollaborators\">\n" + " <item quantity=\"one\">%1$d people</item>\n" + " <item quantity=\"other\">%1$d people</item>\n" + " </plurals>\n" + " <!-- Example2 of plurals -->\n" + " <plurals name=\"numberOfCollaborators2\">\n" + " <item quantity=\"one\">%1$d people</item>\n" + " <item quantity=\"other\">%1$d people</item>\n" + " </plurals>\n" + " <plurals name=\"numberOfCollaborators3\">\n" + " <item quantity=\"other\">%1$d people</item>\n" + " </plurals>\n" + "</resources>"; String expectedLocalizedAsset_jaJP = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<resources>\n" + " <!-- Example of plurals -->\n" + " <plurals name=\"numberOfCollaborators\">\n" + " <item quantity=\"other\">%1$d people</item>\n" + " </plurals>\n" + " <!-- Example2 of plurals -->\n" + " <plurals name=\"numberOfCollaborators2\">\n" + " <item quantity=\"other\">%1$d people</item>\n" + " </plurals>\n" + " <plurals name=\"numberOfCollaborators3\">\n" + " <item quantity=\"other\">%1$d people</item>\n" + " </plurals>\n" + "</resources>"; String expectedLocalizedAsset_enGB = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<resources>\n" + " <!-- Example of plurals -->\n" + " <plurals name=\"numberOfCollaborators\">\n" + " <item quantity=\"one\">%1$d people</item>\n" + " <item quantity=\"other\">%1$d people</item>\n" + " </plurals>\n" + " <!-- Example2 of plurals -->\n" + " <plurals name=\"numberOfCollaborators2\">\n" + " <item quantity=\"one\">%1$d people</item>\n" + " <item quantity=\"other\">%1$d people</item>\n" + " </plurals>\n" + " <plurals name=\"numberOfCollaborators3\">\n" + " <item quantity=\"one\">%1$d people</item>\n" + " <item quantity=\"other\">%1$d people</item>\n" + " </plurals>\n" + "</resources>"; asset = assetService.createAssetWithContent(repo.getId(), "res/values/strings.xml", assetContent); asset = assetRepository.findById(asset.getId()).orElse(null); assetId = asset.getId(); tmId = repo.getTm().getId(); PollableFuture<Asset> assetResult = assetService.addOrUpdateAssetAndProcessIfNeeded(repo.getId(), asset.getPath(), assetContent, false, null, null, null, null); try { pollableTaskService.waitForPollableTask(assetResult.getPollableTask().getId()); } catch (PollableTaskException | InterruptedException e) { throw new RuntimeException(e); } assetResult.get(); TextUnitSearcherParameters textUnitSearcherParameters = new TextUnitSearcherParameters(); textUnitSearcherParameters.setRepositoryIds(repo.getId()); textUnitSearcherParameters.setStatusFilter(StatusFilter.FOR_TRANSLATION); List<TextUnitDTO> textUnitDTOs = textUnitSearcher.search(textUnitSearcherParameters); for (TextUnitDTO textUnitDTO : textUnitDTOs) { logger.debug("source [{}]=[{}]", textUnitDTO.getName(), textUnitDTO.getSource()); } String localizedAsset = tmService.generateLocalized(asset, assetContent, repoLocale, "ja-JP", null, null, Status.ALL, InheritanceMode.USE_PARENT); logger.debug("localized=\n{}", localizedAsset); assertEquals(expectedLocalizedAsset_jaJP, localizedAsset); localizedAsset = tmService.generateLocalized(asset, assetContent, repoLocale, "en-GB", null, null, Status.ALL, InheritanceMode.USE_PARENT); logger.debug("localized=\n{}", localizedAsset); assertEquals(expectedLocalizedAsset_enGB, localizedAsset); }
@Test public void testLocalizeAndroidStringsArrayWithEmptyItem() throws Exception { Repository repo = repositoryService.createRepository(testIdWatcher.getEntityName("repository")); RepositoryLocale repoLocale; try { repoLocale = repositoryService.addRepositoryLocale(repo, "en-GB"); } catch (RepositoryLocaleCreationException e) { throw new RuntimeException(e); } String assetContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<resources>\n" + " <string-array name=\"N_items_failed_to_move\">\n" + " <item/>\n" + " <item>1 item failed to move</item>\n" + " <item>%1$d items failed to move</item>\n" + " </string-array>\n" + "</resources>"; asset = assetService.createAssetWithContent(repo.getId(), "res/values/strings.xml", assetContent); asset = assetRepository.findById(asset.getId()).orElse(null); assetId = asset.getId(); tmId = repo.getTm().getId(); PollableFuture<Asset> assetResult = assetService.addOrUpdateAssetAndProcessIfNeeded(repo.getId(), asset.getPath(), assetContent, false, null, null, null, null); try { pollableTaskService.waitForPollableTask(assetResult.getPollableTask().getId()); } catch (PollableTaskException | InterruptedException e) { throw new RuntimeException(e); } assetResult.get(); TextUnitSearcherParameters textUnitSearcherParameters = new TextUnitSearcherParameters(); textUnitSearcherParameters.setRepositoryIds(repo.getId()); textUnitSearcherParameters.setStatusFilter(StatusFilter.FOR_TRANSLATION); List<TextUnitDTO> textUnitDTOs = textUnitSearcher.search(textUnitSearcherParameters); for (TextUnitDTO textUnitDTO : textUnitDTOs) { logger.debug("source=[{}]", textUnitDTO.getSource()); } String localizedAsset = tmService.generateLocalized(asset, assetContent, repoLocale, "en-GB", null, null, Status.ALL, InheritanceMode.USE_PARENT); logger.debug("localized=\n{}", localizedAsset); assertEquals(assetContent, localizedAsset); }
@Test public void testLocalizeAndroidStringsNoXMLVersion() throws Exception { Repository repo = repositoryService.createRepository(testIdWatcher.getEntityName("repository")); RepositoryLocale repoLocale; try { repoLocale = repositoryService.addRepositoryLocale(repo, "en-GB"); } catch (RepositoryLocaleCreationException e) { throw new RuntimeException(e); } String assetContent = "<resources>\n" + " <string name=\"test\">This is test</string>\n" + "</resources>"; asset = assetService.createAssetWithContent(repo.getId(), "res/values/strings.xml", assetContent); asset = assetRepository.findById(asset.getId()).orElse(null); assetId = asset.getId(); tmId = repo.getTm().getId(); PollableFuture<Asset> assetResult = assetService.addOrUpdateAssetAndProcessIfNeeded(repo.getId(), asset.getPath(), assetContent, false, null, null, null, null); try { pollableTaskService.waitForPollableTask(assetResult.getPollableTask().getId()); } catch (PollableTaskException | InterruptedException e) { throw new RuntimeException(e); } assetResult.get(); TextUnitSearcherParameters textUnitSearcherParameters = new TextUnitSearcherParameters(); textUnitSearcherParameters.setRepositoryIds(repo.getId()); textUnitSearcherParameters.setStatusFilter(StatusFilter.FOR_TRANSLATION); List<TextUnitDTO> textUnitDTOs = textUnitSearcher.search(textUnitSearcherParameters); for (TextUnitDTO textUnitDTO : textUnitDTOs) { logger.debug("source=[{}]", textUnitDTO.getSource()); } String localizedAsset = tmService.generateLocalized(asset, assetContent, repoLocale, "en-GB", null, null, Status.ALL, InheritanceMode.USE_PARENT); logger.debug("localized=\n{}", localizedAsset); assertEquals(assetContent, localizedAsset); }
@Test public void testLocalizeAndroidStringsRemoveUntranslatedSingleItem() throws Exception { Repository repo = repositoryService.createRepository(testIdWatcher.getEntityName("repository")); RepositoryLocale repoLocale; try { repoLocale = repositoryService.addRepositoryLocale(repo, "en-GB"); } catch (RepositoryLocaleCreationException e) { throw new RuntimeException(e); } String assetContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<!-- comment after prolog -->\n\n" + "<resources>\n" + " <string name=\"test\">This is test</string>\n" + "</resources>"; asset = assetService.createAssetWithContent(repo.getId(), "res/values/strings.xml", assetContent); asset = assetRepository.findById(asset.getId()).orElse(null); assetId = asset.getId(); tmId = repo.getTm().getId(); PollableFuture<Asset> assetResult = assetService.addOrUpdateAssetAndProcessIfNeeded(repo.getId(), asset.getPath(), assetContent, false, null, null, null, null); try { pollableTaskService.waitForPollableTask(assetResult.getPollableTask().getId()); } catch (PollableTaskException | InterruptedException e) { throw new RuntimeException(e); } assetResult.get(); String expectedLocalized = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<!-- comment after prolog -->" + "<resources>\n" + "</resources>"; String localizedAsset = tmService.generateLocalized(asset, assetContent, repoLocale, "en-GB", null, null, Status.ALL, InheritanceMode.REMOVE_UNTRANSLATED); logger.debug("localized=\n{}", localizedAsset); assertEquals(localizedAsset, localizedAsset); }
@Test public void testLocalizeMacStringsWithSpecialCharacters() throws Exception { Repository repo = repositoryService.createRepository(testIdWatcher.getEntityName("repository")); RepositoryLocale repoLocale; try { repoLocale = repositoryService.addRepositoryLocale(repo, "en-GB"); } catch (RepositoryLocaleCreationException e) { throw new RuntimeException(e); } String assetContent = "\"100_character_description\" = \"\\\"100\\\" character description:\";\n" + "\"two_lines\" = \"first\\nsecond\";"; asset = assetService.createAssetWithContent(repo.getId(), "en.lproj/Localizable.strings", assetContent); asset = assetRepository.findById(asset.getId()).orElse(null); assetId = asset.getId(); tmId = repo.getTm().getId(); PollableFuture<Asset> assetResult = assetService.addOrUpdateAssetAndProcessIfNeeded(repo.getId(), asset.getPath(), assetContent, false, null, null, null, null); try { pollableTaskService.waitForPollableTask(assetResult.getPollableTask().getId()); } catch (PollableTaskException | InterruptedException e) { throw new RuntimeException(e); } assetResult.get(); TextUnitSearcherParameters textUnitSearcherParameters = new TextUnitSearcherParameters(); textUnitSearcherParameters.setRepositoryIds(repo.getId()); textUnitSearcherParameters.setStatusFilter(StatusFilter.FOR_TRANSLATION); List<TextUnitDTO> textUnitDTOs = textUnitSearcher.search(textUnitSearcherParameters); for (TextUnitDTO textUnitDTO : textUnitDTOs) { logger.debug("source=[{}]", textUnitDTO.getSource()); } String localizedAsset = tmService.generateLocalized(asset, assetContent, repoLocale, "en-GB", null, null, Status.ALL, InheritanceMode.USE_PARENT); logger.debug("localized=\n{}", localizedAsset); assertEquals(assetContent, localizedAsset); }
@Test public void testMacStringsdict() throws Exception { Repository repo = repositoryService.createRepository(testIdWatcher.getEntityName("repository")); RepositoryLocale repoLocale_ja; RepositoryLocale repoLocale_en; try { repoLocale_ja = repositoryService.addRepositoryLocale(repo, "ja-JP"); repoLocale_en = repositoryService.addRepositoryLocale(repo, "en-GB"); } catch (RepositoryLocaleCreationException e) { throw new RuntimeException(e); } String assetContent = "<plist version=\"1.0\">\n" + "<dict>\n" + "<key>plural_recipe_cook_hours</key>\n" + "<dict>\n" + " <key>NSStringLocalizedFormatKey</key>\n" + " <string>%#@hours@ to cook</string>\n" + " <key>hours</key>\n" + " <dict>\n" + " <key>NSStringFormatSpecTypeKey</key>\n" + " <string>NSStringPluralRuleType</string>\n" + " <key>NSStringFormatValueTypeKey</key>\n" + " <string>d</string>\n" + " <key>one</key>\n" + " <string>%d hour to cook</string>\n" + " <key>other</key>\n" + " <string>%d hours to cook</string>\n" + " </dict>\n" + "</dict>\n" + "<key>collaborators</key>\n" + "<dict>\n" + " <key>NSStringLocalizedFormatKey</key>\n" + " <string>%#@collaborators@</string>\n" + " <key>collaborators</key>\n" + " <dict>\n" + " <key>NSStringFormatSpecTypeKey</key>\n" + " <string>NSStringPluralRuleType</string>\n" + " <key>NSStringFormatValueTypeKey</key>\n" + " <string>d</string>\n" + " <key>one</key>\n" + " <string>%d collaborator</string>\n" + " <key>other</key>\n" + " <string>%d collaborators</string>\n" + " </dict>\n" + "</dict>\n" + "</dict>\n" + "</plist>"; String expectedLocalizedAsset_jaJP = "<plist version=\"1.0\">\n" + "<dict>\n" + "<key>plural_recipe_cook_hours</key>\n" + "<dict>\n" + " <key>NSStringLocalizedFormatKey</key>\n" + " <string>%#@hours@ to cook</string>\n" + " <key>hours</key>\n" + " <dict>\n" + " <key>NSStringFormatSpecTypeKey</key>\n" + " <string>NSStringPluralRuleType</string>\n" + " <key>NSStringFormatValueTypeKey</key>\n" + " <string>d</string>\n" + " <key>other</key>\n" + " <string>%d hours to cook</string>\n" + " </dict>\n" + "</dict>\n" + "<key>collaborators</key>\n" + "<dict>\n" + " <key>NSStringLocalizedFormatKey</key>\n" + " <string>%#@collaborators@</string>\n" + " <key>collaborators</key>\n" + " <dict>\n" + " <key>NSStringFormatSpecTypeKey</key>\n" + " <string>NSStringPluralRuleType</string>\n" + " <key>NSStringFormatValueTypeKey</key>\n" + " <string>d</string>\n" + " <key>other</key>\n" + " <string>%d collaborators</string>\n" + " </dict>\n" + "</dict>\n" + "</dict>\n" + "</plist>"; String expectedLocalizedAsset_enGB = "<plist version=\"1.0\">\n" + "<dict>\n" + "<key>plural_recipe_cook_hours</key>\n" + "<dict>\n" + " <key>NSStringLocalizedFormatKey</key>\n" + " <string>%#@hours@ to cook</string>\n" + " <key>hours</key>\n" + " <dict>\n" + " <key>NSStringFormatSpecTypeKey</key>\n" + " <string>NSStringPluralRuleType</string>\n" + " <key>NSStringFormatValueTypeKey</key>\n" + " <string>d</string>\n" + " <key>one</key>\n" + " <string>%d hour to cook</string>\n" + " <key>other</key>\n" + " <string>%d hours to cook</string>\n" + " </dict>\n" + "</dict>\n" + "<key>collaborators</key>\n" + "<dict>\n" + " <key>NSStringLocalizedFormatKey</key>\n" + " <string>%#@collaborators@</string>\n" + " <key>collaborators</key>\n" + " <dict>\n" + " <key>NSStringFormatSpecTypeKey</key>\n" + " <string>NSStringPluralRuleType</string>\n" + " <key>NSStringFormatValueTypeKey</key>\n" + " <string>d</string>\n" + " <key>one</key>\n" + " <string>%d collaborator</string>\n" + " <key>other</key>\n" + " <string>%d collaborators</string>\n" + " </dict>\n" + "</dict>\n" + "</dict>\n" + "</plist>"; asset = assetService.createAssetWithContent(repo.getId(), "Localizable.stringsdict", assetContent); asset = assetRepository.findById(asset.getId()).orElse(null); assetId = asset.getId(); tmId = repo.getTm().getId(); PollableFuture<Asset> assetResult = assetService.addOrUpdateAssetAndProcessIfNeeded(repo.getId(), asset.getPath(), assetContent, false, null, null, null, null); try { pollableTaskService.waitForPollableTask(assetResult.getPollableTask().getId()); } catch (PollableTaskException | InterruptedException e) { throw new RuntimeException(e); } assetResult.get(); TextUnitSearcherParameters textUnitSearcherParameters = new TextUnitSearcherParameters(); textUnitSearcherParameters.setRepositoryIds(repo.getId()); textUnitSearcherParameters.setStatusFilter(StatusFilter.FOR_TRANSLATION); List<TextUnitDTO> textUnitDTOs = textUnitSearcher.search(textUnitSearcherParameters); for (TextUnitDTO textUnitDTO : textUnitDTOs) { logger.debug("source [{}]=[{}]", textUnitDTO.getName(), textUnitDTO.getSource()); } String localizedAsset = tmService.generateLocalized(asset, assetContent, repoLocale_ja, "ja-JP", null, null, Status.ALL, InheritanceMode.USE_PARENT); logger.debug("localized=\n{}", localizedAsset); assertEquals(expectedLocalizedAsset_jaJP, localizedAsset); localizedAsset = tmService.generateLocalized(asset, assetContent, repoLocale_en, "en-GB", null, null, Status.ALL, InheritanceMode.USE_PARENT); logger.debug("localized=\n{}", localizedAsset); assertEquals(expectedLocalizedAsset_enGB, localizedAsset); }
@Test public void testLocalizeMacStringsNamessNotEnclosedInDoubleQuotes() throws Exception { Repository repo = repositoryService.createRepository(testIdWatcher.getEntityName("repository")); RepositoryLocale repoLocale; try { repoLocale = repositoryService.addRepositoryLocale(repo, "en-GB"); } catch (RepositoryLocaleCreationException e) { throw new RuntimeException(e); } String assetContent = "NSUsageDescription = \"Usage description:\";\n"; asset = assetService.createAssetWithContent(repo.getId(), "en.lproj/Localizable.strings", assetContent); asset = assetRepository.findById(asset.getId()).orElse(null); assetId = asset.getId(); tmId = repo.getTm().getId(); PollableFuture<Asset> assetResult = assetService.addOrUpdateAssetAndProcessIfNeeded(repo.getId(), asset.getPath(), assetContent, false, null, null, null, null); try { pollableTaskService.waitForPollableTask(assetResult.getPollableTask().getId()); } catch (PollableTaskException | InterruptedException e) { throw new RuntimeException(e); } assetResult.get(); TextUnitSearcherParameters textUnitSearcherParameters = new TextUnitSearcherParameters(); textUnitSearcherParameters.setRepositoryIds(repo.getId()); textUnitSearcherParameters.setStatusFilter(StatusFilter.FOR_TRANSLATION); List<TextUnitDTO> textUnitDTOs = textUnitSearcher.search(textUnitSearcherParameters); assertEquals(1, textUnitDTOs.size()); for (TextUnitDTO textUnitDTO : textUnitDTOs) { logger.debug("source=[{}]", textUnitDTO.getSource()); } String localizedAsset = tmService.generateLocalized(asset, assetContent, repoLocale, "en-GB", null, null, Status.ALL, InheritanceMode.USE_PARENT); logger.debug("localized=\n{}", localizedAsset); assertEquals(assetContent, localizedAsset); }
@Test public void testLocalizeXtb() throws Exception { Repository repo = repositoryService.createRepository(testIdWatcher.getEntityName("repository")); RepositoryLocale repoLocale; try { repoLocale = repositoryService.addRepositoryLocale(repo, "en-GB"); } catch (RepositoryLocaleCreationException e) { throw new RuntimeException(e); } String assetContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<!DOCTYPE translationbundle>\n" + "<translationbundle lang=\"en-US\">\n" + " <translation id=\"0\" key=\"MSG_DIALOG_OK_\" source=\"lib/closure-library/closure/goog/ui/dialog.js\" desc=\"Standard caption for the dialog 'OK' button.\">OK</translation>\n" + " <translation id=\"1\" key=\"MSG_VIEWER_MENU\" source=\"src/js/box/dicom/viewer/toolbar.js\" desc=\"Tooltip text for the &quot;More&quot; menu.\">More</translation>\n" + " <translation id=\"2\" key=\"MSG_GONSTEAD_STEP\" source=\"src/js/box/dicom/viewer/gonsteaddialog.js\" desc=\"Instructions for the Gonstead method.\">Select the &lt;strong&gt;left Iliac crest&lt;/strong&gt;</translation>\n" + "</translationbundle>"; String expectedContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<translationbundle lang=\"en-US\">\n" + " <translation desc=\"Standard caption for the dialog 'OK' button.\" id=\"0\" key=\"MSG_DIALOG_OK_\" source=\"lib/closure-library/closure/goog/ui/dialog.js\">OK</translation>\n" + " <translation desc=\"Tooltip text for the &quot;More&quot; menu.\" id=\"1\" key=\"MSG_VIEWER_MENU\" source=\"src/js/box/dicom/viewer/toolbar.js\">More</translation>\n" + " <translation desc=\"Instructions for the Gonstead method.\" id=\"2\" key=\"MSG_GONSTEAD_STEP\" source=\"src/js/box/dicom/viewer/gonsteaddialog.js\">Select the &lt;strong&gt;left Iliac crest&lt;/strong&gt;</translation>\n" + "</translationbundle>"; asset = assetService.createAssetWithContent(repo.getId(), "xtb/messages-en-US.xtb", assetContent); asset = assetRepository.findById(asset.getId()).orElse(null); assetId = asset.getId(); tmId = repo.getTm().getId(); PollableFuture<Asset> assetResult = assetService.addOrUpdateAssetAndProcessIfNeeded(repo.getId(), asset.getPath(), assetContent, false, null, null, null, null); try { pollableTaskService.waitForPollableTask(assetResult.getPollableTask().getId()); } catch (PollableTaskException | InterruptedException e) { throw new RuntimeException(e); } assetResult.get(); TextUnitSearcherParameters textUnitSearcherParameters = new TextUnitSearcherParameters(); textUnitSearcherParameters.setRepositoryIds(repo.getId()); textUnitSearcherParameters.setStatusFilter(StatusFilter.FOR_TRANSLATION); List<TextUnitDTO> textUnitDTOs = textUnitSearcher.search(textUnitSearcherParameters); assertEquals(3, textUnitDTOs.size()); for (TextUnitDTO textUnitDTO : textUnitDTOs) { logger.debug("source=[{}]", textUnitDTO.getSource()); } String localizedAsset = tmService.generateLocalized(asset, assetContent, repoLocale, "en-GB", null, null, Status.ALL, InheritanceMode.USE_PARENT); logger.debug("localized=\n{}", localizedAsset); assertEquals(expectedContent, localizedAsset); }
@Test public void testLocalizeJsonWithComments() throws Exception { Repository repo = repositoryService.createRepository(testIdWatcher.getEntityName("repository")); RepositoryLocale repoLocale; try { repoLocale = repositoryService.addRepositoryLocale(repo, "en-GB"); } catch (RepositoryLocaleCreationException e) { throw new RuntimeException(e); } String assetContent = "{\n" + " + " \"hello1\": \"Hello 1\",\n" + " \"hello2\": \"Hello 2\",\n" + " + " + " \"hello3\": \"Hello 3\"\n" + "}"; String expectedContent = "\uFEFF" + assetContent; asset = assetService.createAssetWithContent(repo.getId(), "strings.json", assetContent); asset = assetRepository.findById(asset.getId()).orElse(null); assetId = asset.getId(); tmId = repo.getTm().getId(); PollableFuture<Asset> assetResult = assetService.addOrUpdateAssetAndProcessIfNeeded(repo.getId(), asset.getPath(), assetContent, false, null, null, null, null); try { pollableTaskService.waitForPollableTask(assetResult.getPollableTask().getId()); } catch (PollableTaskException | InterruptedException e) { throw new RuntimeException(e); } assetResult.get(); TextUnitSearcherParameters textUnitSearcherParameters = new TextUnitSearcherParameters(); textUnitSearcherParameters.setRepositoryIds(repo.getId()); textUnitSearcherParameters.setStatusFilter(StatusFilter.FOR_TRANSLATION); List<TextUnitDTO> textUnitDTOs = textUnitSearcher.search(textUnitSearcherParameters); assertEquals(3, textUnitDTOs.size()); assertEquals("Greeting from Main UI 1", textUnitDTOs.get(0).getComment()); assertNull(textUnitDTOs.get(1).getComment()); assertEquals("Greeting from Main UI 3", textUnitDTOs.get(2).getComment()); for (TextUnitDTO textUnitDTO : textUnitDTOs) { logger.debug("name=[{}], source=[{}]", textUnitDTO.getName(), textUnitDTO.getSource()); } String localizedAsset = tmService.generateLocalized(asset, assetContent, repoLocale, "en-GB", null, null, Status.ALL, InheritanceMode.USE_PARENT); logger.debug("localized=\n{}", localizedAsset); assertEquals(expectedContent, localizedAsset); }
@Test public void testLocalizeJson() throws Exception { Repository repo = repositoryService.createRepository(testIdWatcher.getEntityName("repository")); RepositoryLocale repoLocale; try { repoLocale = repositoryService.addRepositoryLocale(repo, "en-GB"); } catch (RepositoryLocaleCreationException e) { throw new RuntimeException(e); } List<String> jsonFilterOptions = Arrays.asList("useFullKeyPath=true", "extractAllPairs=false", "exceptions=.*/string"); String assetContent = "{\n" + " \"this to ignore\": {\n" + " \"k1\": \"v1\"\n" + " },\n" + " \"hello_world\": {\n" + " \"string\": \"Hello World\",\n" + " \"note\": \"The start of every language book.\"\n" + " },\n" + " \"num_photos\": {\n" + " \"string\": \"You have {numPhotos, plural, =0 {no photos.} =1 {one photo.} other {# photos.}}\",\n" + " \"note\": \"A description that shows the number of photos a user has.\"\n" + " }\n" + "}"; String expectedContent = "\uFEFF" + assetContent; asset = assetService.createAssetWithContent(repo.getId(), "strings.json", assetContent); asset = assetRepository.findById(asset.getId()).orElse(null); assetId = asset.getId(); tmId = repo.getTm().getId(); PollableFuture<Asset> assetResult = assetService.addOrUpdateAssetAndProcessIfNeeded(repo.getId(), asset.getPath(), assetContent, false, null, null, null, jsonFilterOptions); try { pollableTaskService.waitForPollableTask(assetResult.getPollableTask().getId()); } catch (PollableTaskException | InterruptedException e) { throw new RuntimeException(e); } assetResult.get(); TextUnitSearcherParameters textUnitSearcherParameters = new TextUnitSearcherParameters(); textUnitSearcherParameters.setRepositoryIds(repo.getId()); textUnitSearcherParameters.setStatusFilter(StatusFilter.FOR_TRANSLATION); List<TextUnitDTO> textUnitDTOs = textUnitSearcher.search(textUnitSearcherParameters); assertEquals(2, textUnitDTOs.size()); for (TextUnitDTO textUnitDTO : textUnitDTOs) { logger.debug("name=[{}], source=[{}]", textUnitDTO.getName(), textUnitDTO.getSource()); } String localizedAsset = tmService.generateLocalized(asset, assetContent, repoLocale, "en-GB", null, jsonFilterOptions, Status.ALL, InheritanceMode.USE_PARENT); logger.debug("localized=\n{}", localizedAsset); assertEquals(expectedContent, localizedAsset); }
@Test public void testLocalizeTSFile() throws Exception { Repository repo = repositoryService.createRepository(testIdWatcher.getEntityName("repository")); RepositoryLocale repoLocale; try { repoLocale = repositoryService.addRepositoryLocale(repo, "en-GB"); } catch (RepositoryLocaleCreationException e) { throw new RuntimeException(e); } String assetContent = "namespace Translations {\n" + " export const en = {\n" + " + " \"loginText\": \"Log In\",\n" + " + " \"signupText\": \"Sign up with `backquote`\",\n" + " \"quotedText\": \"Hello \\\"%s\\\"\",\n" + " \"noComment\": \"String with no comment\\nand newline\",\n" + " + " \"templateText1\": `one line`,\n" + " \"templateText2\": `one line no comment`,\n" + " \"templateText3\": `one line \\`/special\\` character`,\n" + " + " \"templateMultilineText1\": `first line\nsecond line`,\n" + " + " \"templateMultilineText2\": `special character\ncheck \\`/command\\` out`,\n\n" + " };\n" + "}\n" + "\n" + "export default Translations;"; asset = assetService.createAssetWithContent(repo.getId(), "translations.ts", assetContent); asset = assetRepository.findById(asset.getId()).orElse(null); assetId = asset.getId(); tmId = repo.getTm().getId(); PollableFuture<Asset> assetResult = assetService.addOrUpdateAssetAndProcessIfNeeded(repo.getId(), asset.getPath(), assetContent, false, null, null, null, null); try { pollableTaskService.waitForPollableTask(assetResult.getPollableTask().getId()); } catch (PollableTaskException | InterruptedException e) { throw new RuntimeException(e); } assetResult.get(); TextUnitSearcherParameters textUnitSearcherParameters = new TextUnitSearcherParameters(); textUnitSearcherParameters.setRepositoryIds(repo.getId()); textUnitSearcherParameters.setStatusFilter(StatusFilter.FOR_TRANSLATION); List<TextUnitDTO> textUnitDTOs = textUnitSearcher.search(textUnitSearcherParameters); for (TextUnitDTO textUnitDTO : textUnitDTOs) { logger.debug("{}\n{}=[{}]", textUnitDTO.getComment(), textUnitDTO.getName(), textUnitDTO.getSource()); } assertEquals(9, textUnitDTOs.size()); assertEquals("Sign up with `backquote`", textUnitDTOs.get(1).getSource()); assertEquals("Hello \"%s\"", textUnitDTOs.get(2).getSource()); assertEquals("String with no comment\nand newline", textUnitDTOs.get(3).getSource()); assertEquals("special character\ncheck `/command` out", textUnitDTOs.get(8).getSource()); String localizedAsset = tmService.generateLocalized(asset, assetContent, repoLocale, "en-GB", null, null, Status.ALL, InheritanceMode.USE_PARENT); logger.debug("localized=\n{}", localizedAsset); assertEquals(assetContent, localizedAsset); }