Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,46 @@ public static LanguageListOption targetLanguage(String targetLanguage) {
* }</pre>
*/
List<Language> listSupportedLanguages(LanguageListOption... options);

/**
* Detects the language of the provided texts.
*
* <p>Example of detecting the language of some texts:
* <pre> {@code
* List<String> texts = new LinkedList<>();
* texts.add("Hello, World!");
* texts.add("¡Hola Mundo!");
* List<Detection> detections = translate.detect(texts);
* }</pre>
*
* @param texts the texts for which language should be detected
* @return a list of objects containing information on the language detection, one for each
* provided text, in order.
*/
List<Detection> detect(List<String> texts);

/**
* Detects the language of the provided texts.
*
* <p>Example of detecting the language of some texts:
* <pre> {@code
* List<Detection> detections = translate.detect("Hello, World!", "¡Hola Mundo!");
* }</pre>
*
* @param texts the texts for which language should be detected
* @return a list of objects containing information on the language detection, one for each
* provided text, in order.
*/
List<Detection> detect(String... texts);

/**
* Detects the language of the provided text. Returns an object containing information on the
* language detection.
*
* <p>Example of detecting the language a text:
* <pre> {@code
* Detection detection = translate.detect("Hello, World!");
* }</pre>
*/
Detection detect(String text);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,20 @@

import static com.google.cloud.RetryHelper.runWithRetries;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;

import com.google.api.services.translate.model.DetectionsResourceItems;
import com.google.api.services.translate.model.LanguagesResource;
import com.google.cloud.BaseService;
import com.google.cloud.RetryHelper.RetryHelperException;
import com.google.cloud.translate.spi.TranslateRpc;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
Expand All @@ -34,6 +40,14 @@ final class TranslateImpl extends BaseService<TranslateOptions> implements Trans

private final TranslateRpc translateRpc;

private static final Function<List<DetectionsResourceItems>, Detection>
DETECTION_FROM_PB_FUNCTION = new Function<List<DetectionsResourceItems>, Detection>() {
@Override
public Detection apply(List<DetectionsResourceItems> detectionPb) {
return Detection.fromPb(detectionPb.get(0));
}
};

TranslateImpl(TranslateOptions options) {
super(options);
translateRpc = options.rpc();
Expand All @@ -53,6 +67,41 @@ public List<LanguagesResource> call() {
}
}

@Override
public List<Detection> detect(final List<String> texts) {
try {
List<List<DetectionsResourceItems>> detectionsPb =
runWithRetries(new Callable<List<List<DetectionsResourceItems>>>() {
@Override
public List<List<DetectionsResourceItems>> call() {
return translateRpc.detect(texts);
}
}, options().retryParams(), EXCEPTION_HANDLER, options().clock());
Iterator<List<DetectionsResourceItems>> detectionIterator = detectionsPb.iterator();
Iterator<String> textIterator = texts.iterator();
while (detectionIterator.hasNext() && textIterator.hasNext()) {
List<DetectionsResourceItems> detectionPb = detectionIterator.next();
String text = textIterator.next();
checkState(detectionPb != null && !detectionPb.isEmpty(),
"No detection found for text: %s", text);
checkState(detectionPb.size() == 1, "Multiple detections found for text: %s", text);
}
return Lists.transform(detectionsPb, DETECTION_FROM_PB_FUNCTION);
} catch (RetryHelperException e) {
throw TranslateException.translateAndThrow(e);
}
}

@Override
public List<Detection> detect(String... texts) {
return detect(Arrays.asList(texts));
}

@Override
public Detection detect(String text) {
return detect(Collections.singletonList(text)).get(0);
}

private Map<TranslateRpc.Option, ?> optionMap(Option... options) {
Map<TranslateRpc.Option, Object> optionMap = Maps.newEnumMap(TranslateRpc.Option.class);
for (Option option : options) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ private static TranslateException translate(IOException exception) {
}

@Override
public List<List<DetectionsResourceItems>> detect(List<String> text) {
public List<List<DetectionsResourceItems>> detect(List<String> texts) {
try {
List<List<DetectionsResourceItems>> detections =
translate.detections().list(text).setKey(options.apiKey()).execute().getDetections();
translate.detections().list(texts).setKey(options.apiKey()).execute().getDetections();
return detections != null ? detections : ImmutableList.<List<DetectionsResourceItems>>of();
} catch (IOException ex) {
throw translate(ex);
Expand All @@ -82,14 +82,14 @@ public List<LanguagesResource> listSupportedLanguages(Map<Option, ?> optionMap)
}

@Override
public List<TranslationsResource> translate(List<String> text, Map<Option, ?> optionMap) {
public List<TranslationsResource> translate(List<String> texts, Map<Option, ?> optionMap) {
try {
String targetLanguage =
firstNonNull(TARGET_LANGUAGE.getString(optionMap), options.targetLanguage());
final String sourceLanguage = SOURCE_LANGUAGE.getString(optionMap);
List<TranslationsResource> translations =
translate.translations()
.list(text, targetLanguage)
.list(texts, targetLanguage)
.setSource(sourceLanguage)
.setKey(options.apiKey())
.execute()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;

import com.google.api.services.translate.model.DetectionsResourceItems;
import com.google.api.services.translate.model.LanguagesResource;
import com.google.cloud.RetryParams;
import com.google.cloud.translate.Translate.LanguageListOption;
Expand Down Expand Up @@ -56,6 +57,12 @@ public class TranslateImplTest {
private static final Language LANGUAGE4 = Language.fromPb(LANGUAGE4_PB);
private static final List<Language> LANGUAGES1 = ImmutableList.of(LANGUAGE1, LANGUAGE2);
private static final List<Language> LANGUAGES2 = ImmutableList.of(LANGUAGE3, LANGUAGE4);
private static final DetectionsResourceItems DETECTION1_PB =
new DetectionsResourceItems().setLanguage("en").setConfidence(0.9F);
private static final DetectionsResourceItems DETECTION2_PB =
new DetectionsResourceItems().setLanguage("en").setConfidence(0.8F);
private static final Detection DETECTION1 = Detection.fromPb(DETECTION1_PB);
private static final Detection DETECTION2 = Detection.fromPb(DETECTION2_PB);

// Empty TranslateRpc options
private static final Map<TranslateRpc.Option, ?> EMPTY_RPC_OPTIONS = ImmutableMap.of();
Expand Down Expand Up @@ -104,7 +111,7 @@ public void testGetOptions() {
}

@Test
public void testListSupporteLanguages() {
public void testListSupportedLanguages() {
EasyMock.expect(translateRpcMock.listSupportedLanguages(EMPTY_RPC_OPTIONS))
.andReturn(ImmutableList.of(LANGUAGE1_PB, LANGUAGE2_PB));
EasyMock.replay(translateRpcMock);
Expand All @@ -113,7 +120,7 @@ public void testListSupporteLanguages() {
}

@Test
public void testListSupporteLanguagesWithOptions() {
public void testListSupportedLanguagesWithOptions() {
EasyMock.expect(translateRpcMock.listSupportedLanguages(LANGUAGE_LIST_OPTIONS))
.andReturn(ImmutableList.of(LANGUAGE3_PB, LANGUAGE4_PB));
EasyMock.replay(translateRpcMock);
Expand All @@ -122,6 +129,126 @@ public void testListSupporteLanguagesWithOptions() {
LanguageListOption.targetLanguage(TARGET_LANGUAGE)));
}

@Test
public void testDetect() {
String text = "text";
EasyMock.expect(translateRpcMock.detect(ImmutableList.of(text)))
.andReturn(
ImmutableList.<List<DetectionsResourceItems>>of(ImmutableList.of(DETECTION1_PB)));
EasyMock.replay(translateRpcMock);
initializeService();
assertEquals(DETECTION1, translate.detect(text));
}

@Test
public void testDetectMultipleDetections() {
String text = "text";
EasyMock.expect(translateRpcMock.detect(ImmutableList.of(text)))
.andReturn(ImmutableList.<List<DetectionsResourceItems>>of(
ImmutableList.of(DETECTION1_PB, DETECTION2_PB)));
EasyMock.replay(translateRpcMock);
initializeService();
thrown.expect(IllegalStateException.class);
thrown.expectMessage("Multiple detections found for text: text");
translate.detect(text);
}

@Test
public void testDetectNoDetection() {
String text = "text";
EasyMock.expect(translateRpcMock.detect(ImmutableList.of(text)))
.andReturn(ImmutableList.<List<DetectionsResourceItems>>of(
ImmutableList.<DetectionsResourceItems>of()));
EasyMock.replay(translateRpcMock);
initializeService();
thrown.expect(IllegalStateException.class);
thrown.expectMessage("No detection found for text: text");
translate.detect(text);
}

@Test
public void testDetectList() {
String text1 = "text";
String text2 = "other text";
List<String> texts = ImmutableList.of(text1, text2);
EasyMock.expect(translateRpcMock.detect(texts))
.andReturn(ImmutableList.<List<DetectionsResourceItems>>of(
ImmutableList.of(DETECTION1_PB), ImmutableList.of(DETECTION2_PB)));
EasyMock.replay(translateRpcMock);
initializeService();
assertEquals(ImmutableList.of(DETECTION1, DETECTION2), translate.detect(texts));
}

@Test
public void testDetectListMultipleDetections() {
String text1 = "text";
String text2 = "other text";
List<String> texts = ImmutableList.of(text1, text2);
EasyMock.expect(translateRpcMock.detect(texts))
.andReturn(ImmutableList.<List<DetectionsResourceItems>>of(
ImmutableList.of(DETECTION1_PB, DETECTION2_PB), ImmutableList.of(DETECTION1_PB)));
EasyMock.replay(translateRpcMock);
initializeService();
thrown.expect(IllegalStateException.class);
thrown.expectMessage("Multiple detections found for text: text");
translate.detect(texts);
}

@Test
public void testDetectListNoDetection() {
String text1 = "text";
String text2 = "other text";
List<String> texts = ImmutableList.of(text1, text2);
EasyMock.expect(translateRpcMock.detect(texts))
.andReturn(ImmutableList.<List<DetectionsResourceItems>>of(
ImmutableList.of(DETECTION1_PB), ImmutableList.<DetectionsResourceItems>of()));
EasyMock.replay(translateRpcMock);
initializeService();
thrown.expect(IllegalStateException.class);
thrown.expectMessage("No detection found for text: other text");
translate.detect(texts);
}

@Test
public void testDetectVararg() {
String text1 = "text";
String text2 = "other text";
EasyMock.expect(translateRpcMock.detect(ImmutableList.of(text1, text2)))
.andReturn(ImmutableList.<List<DetectionsResourceItems>>of(
ImmutableList.of(DETECTION1_PB), ImmutableList.of(DETECTION2_PB)));
EasyMock.replay(translateRpcMock);
initializeService();
assertEquals(ImmutableList.of(DETECTION1, DETECTION2), translate.detect(text1, text2));
}

@Test
public void testDetectVarargMultipleDetections() {
String text1 = "text";
String text2 = "other text";
EasyMock.expect(translateRpcMock.detect(ImmutableList.of(text1, text2)))
.andReturn(ImmutableList.<List<DetectionsResourceItems>>of(
ImmutableList.of(DETECTION1_PB, DETECTION2_PB), ImmutableList.of(DETECTION1_PB)));
EasyMock.replay(translateRpcMock);
initializeService();
thrown.expect(IllegalStateException.class);
thrown.expectMessage("Multiple detections found for text: text");
translate.detect(text1, text2);
}

@Test
public void testDetectVarargNoDetection() {
String text1 = "text";
String text2 = "other text";
EasyMock.expect(translateRpcMock.detect(ImmutableList.of(text1, text2)))
.andReturn(ImmutableList.<List<DetectionsResourceItems>>of(
ImmutableList.of(DETECTION1_PB), ImmutableList.<DetectionsResourceItems>of()));
EasyMock.replay(translateRpcMock);
initializeService();
thrown.expect(IllegalStateException.class);
thrown.expectMessage("No detection found for text: other text");
translate.detect(text1, text2);
}

@Test
public void testRetryableException() {
EasyMock.expect(translateRpcMock.listSupportedLanguages(EMPTY_RPC_OPTIONS))
Expand Down