Skip to content

Commit b482e83

Browse files
authored
[release] Merge pull request #27 from freenowtech/translations-by-tag
Add support for download translations by tag
2 parents 92cf98f + 56f5de9 commit b482e83

File tree

14 files changed

+597
-61
lines changed

14 files changed

+597
-61
lines changed

pom.xml

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
34
<modelVersion>4.0.0</modelVersion>
45

56
<groupId>com.free-now.apis</groupId>
67
<artifactId>phrase-java-client</artifactId>
7-
<version>2.1.1-SNAPSHOT</version>
8+
<version>3.0.0-SNAPSHOT</version>
89
<name>phrase-api</name>
10+
911
<description>This projects contains of services to handle the translations from [PhraseApp API
10-
v2](http://docs.phraseapp.com/api/v2/). It's supposed to expose Phrase translations as POJO or as File within the java world.</description>
12+
v2](http://docs.phraseapp.com/api/v2/). It's supposed to expose Phrase translations as POJO or as File within the java world.
13+
</description>
14+
1115
<url>https://github.com/freenowtech/phrase-java-client</url>
1216

1317
<licenses>
@@ -67,14 +71,14 @@
6771
<dependency>
6872
<groupId>org.apache.httpcomponents</groupId>
6973
<artifactId>httpclient</artifactId>
70-
<version>4.5.2</version>
74+
<version>4.5.13</version>
7175
</dependency>
7276

7377
<!-- General Java Stuff -->
7478
<dependency>
7579
<groupId>com.google.guava</groupId>
7680
<artifactId>guava</artifactId>
77-
<version>19.0</version>
81+
<version>30.0-jre</version>
7882
</dependency>
7983

8084
<!-- Just the annotations; use this dependency if you want to attach annotations
@@ -117,7 +121,7 @@
117121
<dependency>
118122
<groupId>junit</groupId>
119123
<artifactId>junit</artifactId>
120-
<version>4.12</version>
124+
<version>4.13.1</version>
121125
<scope>test</scope>
122126
</dependency>
123127

@@ -131,7 +135,7 @@
131135
<dependency>
132136
<groupId>ch.qos.logback</groupId>
133137
<artifactId>logback-classic</artifactId>
134-
<version>1.1.6</version>
138+
<version>1.2.9</version>
135139
<scope>test</scope>
136140
</dependency>
137141

src/main/java/com/freenow/apis/phrase/api/localedownload/PhraseLocaleDownloadAPI.java

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public class PhraseLocaleDownloadAPI extends GenericPhraseAPI<byte[]>
3737

3838
private static final String PARAMETER_BRANCH = "branch";
3939

40+
private static final String PARAMETER_TAGS = "tags";
41+
4042
private static final String PHRASE_LOCALES_DOWNLOAD_PATH = "/api/v2/projects/" + PLACEHOLDER_PROJECT_ID +
4143
"/locales/" + PLACEHOLDER_LOCALE_ID + "/download";
4244

@@ -62,19 +64,30 @@ public PhraseLocaleDownloadAPI(final String authToken, final String scheme, fina
6264
super(createRestTemplateWithConverter(), scheme, host, authToken);
6365
}
6466

65-
6667
public byte[] downloadLocale(final String projectId, final String localeId)
6768
{
68-
return downloadLocale(projectId, DEFAULT_BRANCH, localeId, DEFAULT_FILE_FORMAT);
69+
return downloadLocale(projectId, DEFAULT_BRANCH, localeId, DEFAULT_FILE_FORMAT, null);
70+
}
71+
72+
73+
public byte[] downloadLocale(final String projectId, final String localeId, final String tags)
74+
{
75+
return downloadLocale(projectId, DEFAULT_BRANCH, localeId, DEFAULT_FILE_FORMAT, tags);
6976
}
7077

7178

7279
public byte[] downloadLocale(final String projectId, final String localeId, final Format format)
7380
{
74-
return downloadLocale(projectId, DEFAULT_BRANCH, localeId, format);
81+
return downloadLocale(projectId, DEFAULT_BRANCH, localeId, format, null);
82+
}
83+
84+
85+
public byte[] downloadLocale(final String projectId, final String localeId, final Format format, final String tags)
86+
{
87+
return downloadLocale(projectId, DEFAULT_BRANCH, localeId, format, tags);
7588
}
7689

77-
public byte[] downloadLocale(final String projectId, final String branch, final String localeId, final Format format)
90+
public byte[] downloadLocale(final String projectId, final String branch, final String localeId, final Format format, final String tags)
7891
{
7992
Preconditions.checkNotNull(projectId, "ProjectIds may not be null.");
8093
Preconditions.checkNotNull(format, "format may not be null.");
@@ -96,15 +109,21 @@ public byte[] downloadLocale(final String projectId, final String branch, final
96109
parameters.add(new BasicNameValuePair(PARAMETER_BRANCH, branch));
97110
}
98111

112+
if (tags != null && !tags.trim().isEmpty()) {
113+
parameters.add(new BasicNameValuePair(PARAMETER_TAGS, tags));
114+
}
115+
99116
final URIBuilder builder = createUriBuilder(requestPath, parameters);
100117

101-
final HttpEntity<Object> requestEntity = createHttpEntity(requestPath);
118+
final String requestPathEtagCacheKey = requestPath.concat(getNonNullString(tags));
119+
120+
final HttpEntity<Object> requestEntity = createHttpEntity(requestPathEtagCacheKey);
102121

103122
final URI uri = builder.build();
104123

105124
final ResponseEntity<byte[]> responseEntity = requestPhrase(requestEntity, uri, byte[].class);
106125

107-
return handleResponse(projectId, requestPath, responseEntity);
126+
return handleResponse(projectId, requestPathEtagCacheKey, responseEntity);
108127

109128
}
110129
catch (final URISyntaxException e)
@@ -123,4 +142,8 @@ private String createDownloadLocaleRequestPath(final String projectId, final Str
123142
return createPath(PHRASE_LOCALES_DOWNLOAD_PATH, placeholders);
124143
}
125144

145+
private String getNonNullString(final String value) {
146+
if (value == null) return "";
147+
return value.trim();
148+
}
126149
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package com.freenow.apis.phrase.api.tag;
2+
3+
import com.freenow.apis.phrase.api.GenericPhraseAPI;
4+
import com.freenow.apis.phrase.api.tag.dto.PhraseTagWithStatsDTO;
5+
import com.freenow.apis.phrase.exception.PhraseAppApiException;
6+
import com.google.common.base.Preconditions;
7+
import java.net.URI;
8+
import java.net.URISyntaxException;
9+
import java.util.ArrayList;
10+
import java.util.Collections;
11+
import java.util.HashMap;
12+
import java.util.List;
13+
import java.util.Map;
14+
import org.apache.http.NameValuePair;
15+
import org.apache.http.message.BasicNameValuePair;
16+
import org.slf4j.Logger;
17+
import org.slf4j.LoggerFactory;
18+
import org.springframework.http.HttpEntity;
19+
import org.springframework.http.ResponseEntity;
20+
import org.springframework.web.client.RestTemplate;
21+
22+
import static com.freenow.apis.phrase.api.localedownload.PhraseLocaleDownloadAPI.DEFAULT_BRANCH;
23+
24+
public class PhraseTagAPI extends GenericPhraseAPI<PhraseTagWithStatsDTO>
25+
{
26+
private static final Logger LOG = LoggerFactory.getLogger(PhraseTagAPI.class);
27+
28+
// ---- configuration -----
29+
private static final String PLACEHOLDER_PROJECT_ID = "{projectid}";
30+
31+
private static final String PLACEHOLDER_TAG_NAME = "{tagName}";
32+
33+
private static final String PHRASE_TRANSLATIONS_PATH = "/api/v2/projects/" + PLACEHOLDER_PROJECT_ID + "/tags/" + PLACEHOLDER_TAG_NAME;
34+
35+
private static final String PARAMETER_BRANCH = "branch";
36+
37+
38+
protected PhraseTagAPI(final RestTemplate restTemplate, final String authToken)
39+
{
40+
super(restTemplate, authToken);
41+
}
42+
43+
44+
public PhraseTagAPI(final String authToken, final String scheme, final String host)
45+
{
46+
super(createRestTemplateWithConverter(), scheme, host, authToken);
47+
}
48+
49+
50+
public PhraseTagAPI(final String authToken)
51+
{
52+
super(createRestTemplateWithConverter(), authToken);
53+
}
54+
55+
56+
public PhraseTagWithStatsDTO getSingleTag(String projectId, String tagName) throws PhraseAppApiException
57+
{
58+
return getSingleTag(projectId, DEFAULT_BRANCH, tagName);
59+
}
60+
61+
62+
public PhraseTagWithStatsDTO getSingleTag(final String projectId, final String branch, final String tagName) throws PhraseAppApiException
63+
{
64+
Preconditions.checkNotNull(projectId, "ProjectId must not be null.");
65+
Preconditions.checkNotNull(tagName, "Tag name must not be null.");
66+
LOG.trace("Start to retrieve tag for projectId: {} and name: {}", projectId, tagName);
67+
68+
try
69+
{
70+
final String requestPath = createRequestPath(projectId, tagName);
71+
72+
LOG.trace("Call requestPath: {} to get tag from phrase.", requestPath);
73+
74+
final List<NameValuePair> parameters;
75+
if (!DEFAULT_BRANCH.equals(branch))
76+
{
77+
parameters = new ArrayList<>(1);
78+
parameters.add(new BasicNameValuePair(PARAMETER_BRANCH, branch));
79+
}
80+
else
81+
{
82+
parameters = Collections.emptyList();
83+
}
84+
85+
final URI uri = createUriBuilder(requestPath, parameters)
86+
.build();
87+
88+
final HttpEntity<Object> requestEntity = createHttpEntity(requestPath);
89+
90+
final ResponseEntity<PhraseTagWithStatsDTO> responseEntity = requestPhrase(
91+
requestEntity,
92+
uri,
93+
PhraseTagWithStatsDTO.class);
94+
95+
return handleResponse(projectId, requestPath, responseEntity);
96+
}
97+
catch (URISyntaxException e)
98+
{
99+
throw new RuntimeException("Something goes wrong due building of the request URI", e);
100+
}
101+
}
102+
103+
104+
private String createRequestPath(final String projectId, final String tagName)
105+
{
106+
Map<String, String> placeholders = new HashMap<String, String>();
107+
placeholders.put(PLACEHOLDER_PROJECT_ID, projectId);
108+
placeholders.put(PLACEHOLDER_TAG_NAME, tagName);
109+
return createPath(PHRASE_TRANSLATIONS_PATH, placeholders);
110+
}
111+
112+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.freenow.apis.phrase.api.tag.dto;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
5+
@JsonIgnoreProperties(ignoreUnknown = true)
6+
public class LocalePreviewDTO {
7+
8+
private String id;
9+
10+
private String name;
11+
12+
private String code;
13+
14+
private LocalePreviewWithStatsStatisticsDTO statistics;
15+
16+
public LocalePreviewDTO() {
17+
}
18+
19+
public LocalePreviewDTO(
20+
final String id,
21+
final String name,
22+
final String code,
23+
final LocalePreviewWithStatsStatisticsDTO statistics) {
24+
this.id = id;
25+
this.name = name;
26+
this.code = code;
27+
this.statistics = statistics;
28+
}
29+
30+
public String getId() {
31+
return id;
32+
}
33+
34+
public void setId(final String id) {
35+
this.id = id;
36+
}
37+
38+
public String getName() {
39+
return name;
40+
}
41+
42+
public void setName(final String name) {
43+
this.name = name;
44+
}
45+
46+
public String getCode() {
47+
return code;
48+
}
49+
50+
public void setCode(final String code) {
51+
this.code = code;
52+
}
53+
54+
public LocalePreviewWithStatsStatisticsDTO getStatistics() {
55+
return statistics;
56+
}
57+
58+
public void setStatistics(LocalePreviewWithStatsStatisticsDTO statistics) {
59+
this.statistics = statistics;
60+
}
61+
62+
@Override
63+
public String toString() {
64+
return String.format("LocalePreviewDTO{id='%s', name='%s', code='%s'}", id, name, code);
65+
}
66+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.freenow.apis.phrase.api.tag.dto;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
6+
@JsonIgnoreProperties(ignoreUnknown = true)
7+
public class LocalePreviewWithStatsStatisticsDTO {
8+
9+
@JsonProperty("keys_total_count")
10+
private Integer keysTotalCount;
11+
12+
@JsonProperty("translations_completed_count")
13+
private Integer translationsCompletedCount;
14+
15+
@JsonProperty("translations_unverified_count")
16+
private Integer translationsUnverifiedCount;
17+
18+
@JsonProperty("keys_untranslated_count")
19+
private Integer keysUntranslatedCount;
20+
21+
public LocalePreviewWithStatsStatisticsDTO() { }
22+
23+
public LocalePreviewWithStatsStatisticsDTO(
24+
final Integer keysTotalCount,
25+
final Integer translationsCompletedCount,
26+
final Integer translationsUnverifiedCount,
27+
final Integer keysUntranslatedCount
28+
) {
29+
this.keysTotalCount = keysTotalCount;
30+
this.translationsCompletedCount = translationsCompletedCount;
31+
this.translationsUnverifiedCount = translationsUnverifiedCount;
32+
this.keysUntranslatedCount = keysUntranslatedCount;
33+
}
34+
35+
public Integer getKeysTotalCount() {
36+
return keysTotalCount;
37+
}
38+
39+
public void setKeysTotalCount(Integer keysTotalCount) {
40+
this.keysTotalCount = keysTotalCount;
41+
}
42+
43+
public Integer getTranslationsCompletedCount() {
44+
return translationsCompletedCount;
45+
}
46+
47+
public void setTranslationsCompletedCount(Integer translationsCompletedCount) {
48+
this.translationsCompletedCount = translationsCompletedCount;
49+
}
50+
51+
public Integer getTranslationsUnverifiedCount() {
52+
return translationsUnverifiedCount;
53+
}
54+
55+
public void setTranslationsUnverifiedCount(Integer translationsUnverifiedCount) {
56+
this.translationsUnverifiedCount = translationsUnverifiedCount;
57+
}
58+
59+
public Integer getKeysUntranslatedCount() {
60+
return keysUntranslatedCount;
61+
}
62+
63+
public void setKeysUntranslatedCount(Integer keysUntranslatedCount) {
64+
this.keysUntranslatedCount = keysUntranslatedCount;
65+
}
66+
}

0 commit comments

Comments
 (0)