VirtualAssetService { public TMTextUnitVariant addTextUnitVariant(long assetId, long localeId, String name, String content, String comment) throws VirtualAssetRequiredException, VirutalAssetMissingTextUnitException { logger.debug("Add text unit variant to virtual assetId: {}, with name: {}", assetId, name); TextUnitSearcherParameters textUnitSearcherParameters = new TextUnitSearcherParameters(); textUnitSearcherParameters.setAssetId(assetId); textUnitSearcherParameters.setName(name); textUnitSearcherParameters.setSearchType(SearchType.EXACT); textUnitSearcherParameters.setUsedFilter(UsedFilter.USED); textUnitSearcherParameters.setLimit(1); List<TextUnitDTO> textUnitDTOs = textUnitSearcher.search(textUnitSearcherParameters); if (textUnitDTOs.isEmpty()) { textUnitSearcherParameters.setUsedFilter(UsedFilter.UNUSED); textUnitDTOs = textUnitSearcher.search(textUnitSearcherParameters); } if (textUnitDTOs.isEmpty()) { String msg = MessageFormat.format("Missing TmTextUnit for assetId: {0} and name: {1}", assetId, name); logger.debug(msg); throw new VirutalAssetMissingTextUnitException(msg); } return tmService.addCurrentTMTextUnitVariant(textUnitDTOs.get(0).getTmTextUnitId(), localeId, content); }  @Transactional VirtualAsset createOrUpdateVirtualAsset(VirtualAsset virtualAsset); List<VirtualAssetTextUnit> getTextUnits(long assetId, Boolean doNotTranslateFilter); @Transactional List<VirtualAssetTextUnit> getLocalizedTextUnits(
            long assetId,
            long localeId,
            InheritanceMode inheritanceMode); PollableFuture<Void> addTextUnits(long assetId, List<VirtualAssetTextUnit> virtualAssetTextUnits); PollableFuture<Void> replaceTextUnits(long assetId, List<VirtualAssetTextUnit> virtualAssetTextUnits); PollableFuture<Void> importLocalizedTextUnits(
            long assetId,
            long localeId,
            List<VirtualAssetTextUnit> textUnitForVirtualAssets); @Transactional void deleteTextUnit(Long assetId, String name); void deleteTextUnits(Asset asset, List<String> names); TMTextUnitVariant addTextUnitVariant(long assetId, long localeId, String name, String content, String comment);  }
@Test public void testAddTextUnitVariant() throws Exception { Repository repository = repositoryService.createRepository(testIdWatcher.getEntityName("testAddTextUnitVariant")); RepositoryLocale repositoryLocaleFrFR = repositoryService.addRepositoryLocale(repository, "fr-FR"); long frFRLocaleId = repositoryLocaleFrFR.getLocale().getId(); VirtualAsset virtualAsset = new VirtualAsset(); virtualAsset.setRepositoryId(repository.getId()); virtualAsset.setPath("default"); virtualAsset = virtualAssetService.createOrUpdateVirtualAsset(virtualAsset); virtualAssetService.addTextUnit( virtualAsset.getId(), "name_plural_other", "content plural", "comment plural", "other", "name_plural_other", false); TMTextUnitVariant addTextUnitVariant = virtualAssetService.addTextUnitVariant(virtualAsset.getId(), frFRLocaleId, "name_plural_other", "content-fr", "comment-fr"); Assert.assertNotNull(addTextUnitVariant.getId()); List<VirtualAssetTextUnit> loalizedTextUnits = virtualAssetService.getLocalizedTextUnits(virtualAsset.getId(), frFRLocaleId, InheritanceMode.REMOVE_UNTRANSLATED); assertEquals(1, loalizedTextUnits.size()); int i = 0; assertEquals("name_plural_other", loalizedTextUnits.get(i).getName()); assertEquals("content-fr", loalizedTextUnits.get(i).getContent()); assertEquals("comment plural", loalizedTextUnits.get(i).getComment()); assertEquals("other", loalizedTextUnits.get(i).getPluralForm()); assertEquals("name_plural_other", loalizedTextUnits.get(i).getPluralFormOther()); }