diff --git a/server/zanata-war/src/main/java/org/zanata/rest/service/ResourceUtils.java b/server/zanata-war/src/main/java/org/zanata/rest/service/ResourceUtils.java index 11e530a1aa..0ab4cb1b48 100644 --- a/server/zanata-war/src/main/java/org/zanata/rest/service/ResourceUtils.java +++ b/server/zanata-war/src/main/java/org/zanata/rest/service/ResourceUtils.java @@ -74,15 +74,15 @@ public class ResourceUtils /** * Newline character used for multi-line comments */ - private static final char NEWLINE = '\n'; + private static final char NEWLINE = '\n'; - private static final String ZANATA_GENERATOR_PREFIX = "Zanata"; + private static final String ZANATA_GENERATOR_PREFIX = "Zanata"; - private static final String ZANATA_TAG = "#zanata"; + private static final String ZANATA_TAG = "#zanata"; - private static final String PO_DATE_FORMAT = "yyyy-MM-dd hh:mmZ"; + private static final String PO_DATE_FORMAT = "yyyy-MM-dd hh:mmZ"; - private static final String PO_VALID_CONTENT_TYPE = "charset=UTF-8"; + private static final String[] PO_VALID_CONTENT_TYPES = {"charset=UTF-8", "charset=utf-8", "charset=ASCII"}; /** @@ -1171,7 +1171,13 @@ public boolean validateResourceEncoding(Resource res) { if( entry.getKey().equalsIgnoreCase( CONTENT_TYPE_HDR ) ) { - return entry.getValue().contains( PO_VALID_CONTENT_TYPE ); + for( String acceptedContentType : PO_VALID_CONTENT_TYPES ) + { + if( entry.getValue().contains( acceptedContentType ) ) + { + return true; + } + } } } diff --git a/server/zanata-war/src/main/java/org/zanata/rest/service/TranslationResourcesService.java b/server/zanata-war/src/main/java/org/zanata/rest/service/TranslationResourcesService.java index ba39c8b014..d3fd64f0f7 100644 --- a/server/zanata-war/src/main/java/org/zanata/rest/service/TranslationResourcesService.java +++ b/server/zanata-war/src/main/java/org/zanata/rest/service/TranslationResourcesService.java @@ -415,7 +415,7 @@ public Response putResource(@PathParam("id") String idNoSlash, InputStream messa Resource entity = RestUtils.unmarshall(Resource.class, messageBody, requestContentType, headers.getRequestHeaders()); log.debug("resource details: {0}", entity); - validateResourceEncoding(entity); + boolean validResourceEnc = this.resourceUtils.validateResourceEncoding(entity); HDocument document = documentDAO.getByDocId(hProjectIteration, id); HLocale hLocale = validateSourceLocale(entity.getLang()); @@ -476,6 +476,11 @@ else if (document.isObsolete()) { copyClosestEquivalentTranslation(document.getId(), entity.getName(), projectSlug, iterationSlug); } + + if( !validResourceEnc ) + { + response.entity("warning: potentially incompatible character encoding."); + } log.debug("put resource successfully"); return response.tag(etag).build(); @@ -914,14 +919,6 @@ private void validateExtensions(String... validExt) throws WebApplicationExcepti } } - private void validateResourceEncoding(Resource res) throws WebApplicationException - { - if( !this.resourceUtils.validateResourceEncoding(res) ) - { - throw new WebApplicationException(Response.status(Status.UNSUPPORTED_MEDIA_TYPE).entity("Unsupported Encoding: ").build()); - } - } - public void copyClosestEquivalentTranslation(Long docId, String name, String projectSlug, String iterationSlug) { diff --git a/server/zanata-war/src/test/java/org/zanata/rest/service/ResourceTestUtil.java b/server/zanata-war/src/test/java/org/zanata/rest/service/ResourceTestUtil.java index a4600bf9b0..034b5ae7ab 100644 --- a/server/zanata-war/src/test/java/org/zanata/rest/service/ResourceTestUtil.java +++ b/server/zanata-war/src/test/java/org/zanata/rest/service/ResourceTestUtil.java @@ -3,6 +3,8 @@ import java.util.Iterator; import java.util.List; +import org.zanata.rest.dto.extensions.gettext.HeaderEntry; +import org.zanata.rest.dto.extensions.gettext.PoHeader; import org.zanata.rest.dto.extensions.gettext.PoTargetHeader; import org.zanata.rest.dto.extensions.gettext.TranslationsResourceExtension; import org.zanata.rest.dto.resource.AbstractResourceMeta; @@ -56,5 +58,18 @@ static void clearPoTargetHeaders(TranslationsResource ... docs) } } } + + static void addPoHeader( Resource res, String key, String value ) + { + PoHeader poHeader = res.getExtensions(true).findByType(PoHeader.class); + + if( poHeader == null ) + { + poHeader = new PoHeader(); + res.getExtensions().add(poHeader); + } + + poHeader.getEntries().add( new HeaderEntry(key, value) ); + } } diff --git a/server/zanata-war/src/test/java/org/zanata/rest/service/TranslationResourceRestTest.java b/server/zanata-war/src/test/java/org/zanata/rest/service/TranslationResourceRestTest.java index 6d59715bcd..2870207d25 100644 --- a/server/zanata-war/src/test/java/org/zanata/rest/service/TranslationResourceRestTest.java +++ b/server/zanata-war/src/test/java/org/zanata/rest/service/TranslationResourceRestTest.java @@ -715,8 +715,22 @@ public void getBadProject() throws Exception ClientResponse> response = badTransResource.get(null); assertThat(response.getStatus(), is(404)); } + + @Test + public void putUnexpectedEncodingDocument() throws Exception + { + Resource doc = this.createSourceDoc("DocumentWithUnexpectedEncoding", true); + ResourceTestUtil.addPoHeader(doc, "Content-Type", "application/x-publican; charset=UNACCEPTABLE"); + ClientResponse response = this.putResource(doc, "gettext"); + assertThat(response.getEntity(), containsString("warning")); + } // END of tests + + private ClientResponse putResource( Resource res, String extensions ) + { + return transResource.putResource(res.getName(), res, new StringSet( extensions )); + } private void expectDocs(boolean checkRevs, boolean checkLinksIgnored, Resource... docs) {