diff --git a/zanata-client-commands/src/main/java/org/zanata/client/commands/FileMappingRuleParser.java b/zanata-client-commands/src/main/java/org/zanata/client/commands/FileMappingRuleParser.java index a0940f2a..21f216f3 100644 --- a/zanata-client-commands/src/main/java/org/zanata/client/commands/FileMappingRuleParser.java +++ b/zanata-client-commands/src/main/java/org/zanata/client/commands/FileMappingRuleParser.java @@ -31,6 +31,7 @@ import javax.annotation.Nonnull; +import org.apache.commons.io.FilenameUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.zanata.client.config.FileMappingRule; @@ -76,8 +77,7 @@ public boolean isApplicable(QualifiedSrcDocName qualifiedSrcDocName) { } private boolean matchFileExtensionWithProjectType(QualifiedSrcDocName qualifiedSrcDocName) { - List supportedTypes = - ProjectType.getSupportedSourceFileTypes(projectType); + List supportedTypes = projectType.getSourceFileTypes(); return supportedTypes.contains(qualifiedSrcDocName.getExtension()); } @@ -101,14 +101,14 @@ protected static EnumMap parseToMap( new EnumMap(Placeholders.class); File file = new File(sourceFile); String extension = Files.getFileExtension(sourceFile); - String filename = - file.getName().replaceFirst("\\." + extension + "$", ""); + String filename = FilenameUtils.removeExtension(file.getName()); parts.put(Placeholders.extension, extension); parts.put(Placeholders.filename, filename); parts.put(Placeholders.locale, originalLocale.getLocalLocale()); parts.put(Placeholders.localeWithUnderscore, originalLocale.getLocalLocale().replaceAll("\\-", "_")); - parts.put(Placeholders.path, Files.simplifyPath(file.getParent())); + String pathname = Strings.nullToEmpty(file.getParent()); + parts.put(Placeholders.path, Files.simplifyPath(pathname)); log.debug("parsed parts: {}", parts); return parts; } diff --git a/zanata-client-commands/src/main/java/org/zanata/client/commands/TransFileResolver.java b/zanata-client-commands/src/main/java/org/zanata/client/commands/TransFileResolver.java index 312152d4..1e934e93 100644 --- a/zanata-client-commands/src/main/java/org/zanata/client/commands/TransFileResolver.java +++ b/zanata-client-commands/src/main/java/org/zanata/client/commands/TransFileResolver.java @@ -35,6 +35,7 @@ import java.util.List; import java.util.Map; +import static com.google.common.base.Preconditions.checkState; import static org.zanata.client.commands.Messages._; /** @@ -56,6 +57,8 @@ public class TransFileResolver { "{path}/{filename}_{locale_with_underscore}.{extension}")) .put(ProjectType.Utf8Properties, new FileMappingRule( "{path}/{filename}_{locale_with_underscore}.{extension}")) + .put(ProjectType.Xliff, new FileMappingRule( + "{path}/{filename}_{locale_with_underscore}.{extension}")) .build(); public TransFileResolver(ConfigurableProjectOptions opts) { @@ -96,8 +99,7 @@ private File getDefaultTransFileFromProjectType( QualifiedSrcDocName qualifiedSrcDocName, LocaleMapping localeMapping, ProjectType projectType) { FileMappingRule rule = defaultProjectTypeToRules.get(projectType); - Preconditions - .checkNotNull(rule, _("no.default.mapping"), projectType); + checkState(rule != null, _("no.default.mapping"), projectType); String relativePath = new FileMappingRuleParser(rule, projectType) .getRelativePathFromRule(qualifiedSrcDocName, localeMapping); return new File(opts.getTransDir(), relativePath); diff --git a/zanata-client-commands/src/main/java/org/zanata/client/commands/push/XliffStrategy.java b/zanata-client-commands/src/main/java/org/zanata/client/commands/push/XliffStrategy.java index 892fdf11..c9315822 100644 --- a/zanata-client-commands/src/main/java/org/zanata/client/commands/push/XliffStrategy.java +++ b/zanata-client-commands/src/main/java/org/zanata/client/commands/push/XliffStrategy.java @@ -6,10 +6,12 @@ import java.util.HashSet; import java.util.Set; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang.StringUtils; import org.zanata.adapter.xliff.XliffReader; +import org.zanata.client.commands.TransFileResolver; import org.zanata.client.commands.push.PushCommand.TranslationResourcesVisitor; import org.zanata.client.config.LocaleMapping; import org.zanata.common.LocaleId; @@ -25,6 +27,12 @@ public XliffStrategy() { super(new StringSet("comment"), ".xml"); } + @VisibleForTesting + protected XliffStrategy(XliffReader reader) { + super(new StringSet("comment"), ".xml"); + this.reader = reader; + } + @Override public Set findDocNames(File srcDir, ImmutableList includes, ImmutableList excludes, boolean useDefaultExclude, @@ -74,8 +82,9 @@ public Resource loadSrcDoc(File sourceDir, String docName) public void visitTranslationResources(String docName, Resource srcDoc, TranslationResourcesVisitor visitor) throws FileNotFoundException { for (LocaleMapping locale : getOpts().getLocaleMapList()) { - String filename = docNameToFilename(docName, locale); - File transFile = new File(getOpts().getTransDir(), filename); + File transFile = new TransFileResolver(getOpts()).getTransFile( + TransFileResolver.UnqualifiedSrcDocName.from(docName), + locale); if (transFile.exists()) { TranslationsResource targetDoc = reader.extractTarget(transFile); diff --git a/zanata-client-commands/src/test/java/org/zanata/client/commands/push/XliffStrategyTest.java b/zanata-client-commands/src/test/java/org/zanata/client/commands/push/XliffStrategyTest.java new file mode 100644 index 00000000..4f5ea44f --- /dev/null +++ b/zanata-client-commands/src/test/java/org/zanata/client/commands/push/XliffStrategyTest.java @@ -0,0 +1,149 @@ +/* + * Copyright 2014, Red Hat, Inc. and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.zanata.client.commands.push; + +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.zanata.client.TestUtils.createAndAddLocaleMapping; + +import java.io.File; +import java.io.IOException; + +import org.hamcrest.Matchers; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.zanata.adapter.xliff.XliffReader; +import org.zanata.client.TempTransFileRule; +import org.zanata.client.config.FileMappingRule; +import org.zanata.client.config.LocaleList; +import org.zanata.client.config.LocaleMapping; +import org.zanata.rest.dto.resource.Resource; +import org.zanata.rest.dto.resource.TranslationsResource; + +import com.google.common.base.Optional; +import com.google.common.collect.Lists; + +public class XliffStrategyTest { + + @Rule + public TempTransFileRule tempFileRule = new TempTransFileRule(); + private XliffStrategy strategy; + private PushOptionsImpl opts; + @Captor + private ArgumentCaptor transResourceCaptor; + @Mock + private PushCommand.TranslationResourcesVisitor visitor; + private Resource sourceResource; + @Mock + private XliffReader reader; + @Captor + private ArgumentCaptor fileCapture; + + @Before + public void setUp() throws IOException { + MockitoAnnotations.initMocks(this); + strategy = new XliffStrategy(reader); + opts = new PushOptionsImpl(); + opts.setLocaleMapList(new LocaleList()); + opts.setTransDir(tempFileRule.getTransDir()); + opts.setProjectType("xliff"); + strategy.setPushOptions(opts); + + sourceResource = new Resource("test"); + } + + @Test + public void canVisitTranslationFileWithoutFileMapping() throws Exception { + // with translation + LocaleMapping deMapping = createAndAddLocaleMapping("de", + Optional. absent(), opts); + // with translation and has map-from + LocaleMapping zhMapping = + createAndAddLocaleMapping("zh-CN", + Optional.of("zh-Hans"), + opts); + // no translation + opts.getLocaleMapList().add(new LocaleMapping("ja")); + + File deTransFile = + tempFileRule.createTransFileRelativeToTransDir( + "foo/message_de.xml"); + File zhTransFile = + tempFileRule.createTransFileRelativeToTransDir( + "foo/message_zh_Hans.xml"); + + strategy.visitTranslationResources("foo/message", + sourceResource, visitor); + + verify(visitor).visit(eq(deMapping), transResourceCaptor.capture()); + verify(visitor).visit(eq(zhMapping), transResourceCaptor.capture()); + verify(reader, times(2)).extractTarget(fileCapture.capture()); + assertThat(fileCapture.getAllValues(), + Matchers.contains(deTransFile, zhTransFile)); + + verifyNoMoreInteractions(visitor); + } + + @Test + public void canVisitTranslationFileUsingFileMapping() throws Exception { + // with translation + LocaleMapping deMapping = createAndAddLocaleMapping("de", + Optional. absent(), opts); + // with translation and has map-from + LocaleMapping zhMapping = + createAndAddLocaleMapping("zh-CN", + Optional.of("zh-Hans"), + opts); + // no translation + opts.getLocaleMapList().add(new LocaleMapping("ja")); + + File deTransFile = + tempFileRule.createTransFileRelativeToTransDir( + "foo/message_de.xml"); + File zhTransFile = + tempFileRule.createTransFileRelativeToTransDir( + "foo/message_zh_Hans.xml"); + + opts.setFileMappingRules(Lists.newArrayList(new FileMappingRule( + "{path}/{filename}_{locale_with_underscore}.{extension}"))); + + strategy.visitTranslationResources("foo/message", + sourceResource, visitor); + + verify(visitor).visit(eq(deMapping), transResourceCaptor.capture()); + verify(visitor).visit(eq(zhMapping), transResourceCaptor.capture()); + verify(reader, times(2)).extractTarget(fileCapture.capture()); + assertThat(fileCapture.getAllValues(), + Matchers.contains(deTransFile, zhTransFile)); + + verifyNoMoreInteractions(visitor); + } + +}