You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by rm...@apache.org on 2019/09/28 17:15:25 UTC

[johnzon] branch master updated: JOHNZON-284 respect user charset when provided

This is an automated email from the ASF dual-hosted git repository.

rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/johnzon.git


The following commit(s) were added to refs/heads/master by this push:
     new fee2958  JOHNZON-284 respect user charset when provided
fee2958 is described below

commit fee2958377a803cc31dcc07801827137f9660105
Author: Romain Manni-Bucau <rm...@apache.org>
AuthorDate: Sat Sep 28 19:15:14 2019 +0200

    JOHNZON-284 respect user charset when provided
---
 .../java/org/apache/johnzon/core/AbstractJsonFactory.java | 10 ++++++++++
 .../org/apache/johnzon/core/JsonParserFactoryImpl.java    |  9 ++++++++-
 .../org/apache/johnzon/core/JsonStreamParserImpl.java     | 10 +++++++---
 .../johnzon/core/RFC4627AwareInputStreamReader.java       | 15 ++++++---------
 .../johnzon/jaxrs/jsonb/jaxrs/JsonbJaxrsProvider.java     |  4 ++--
 .../java/org/apache/johnzon/mapper/MapperBuilder.java     | 15 +++++++++------
 6 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/AbstractJsonFactory.java b/johnzon-core/src/main/java/org/apache/johnzon/core/AbstractJsonFactory.java
index 40194bd..ded93e3 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/AbstractJsonFactory.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/AbstractJsonFactory.java
@@ -78,4 +78,14 @@ public abstract class AbstractJsonFactory implements Serializable {
         return Boolean.parseBoolean(boolValue.toString());
     }
 
+    protected String getString(final String key, final String defaultValue) {
+        final Object value = internalConfig.get(key);
+        if (value == null) {
+            return defaultValue;
+        } else if (String.class.isInstance(value)) {
+            return String.class.cast(value);
+        }
+        return value.toString();
+    }
+
 }
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonParserFactoryImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonParserFactoryImpl.java
index 437a2ca..a1651df 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonParserFactoryImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonParserFactoryImpl.java
@@ -30,6 +30,7 @@ import java.util.Collections;
 import java.util.Map;
 
 import static java.util.Arrays.asList;
+import static java.util.Optional.ofNullable;
 
 public class JsonParserFactoryImpl extends AbstractJsonFactory implements JsonParserFactory {
     public static final String MAX_STRING_LENGTH = "org.apache.johnzon.max-string-length";
@@ -40,10 +41,11 @@ public class JsonParserFactoryImpl extends AbstractJsonFactory implements JsonPa
     public static final int DEFAULT_BUFFER_LENGTH = Integer.getInteger(BUFFER_LENGTH, 64 * 1024); //64k
     
     public static final String SUPPORTS_COMMENTS = "org.apache.johnzon.supports-comments";
+    public static final String ENCODING = "org.apache.johnzon.encoding";
     public static final boolean DEFAULT_SUPPORTS_COMMENT = Boolean.getBoolean(SUPPORTS_COMMENTS); //default is false;
 
     static final Collection<String> SUPPORTED_CONFIG_KEYS = asList(
-        BUFFER_STRATEGY, MAX_STRING_LENGTH, BUFFER_LENGTH, SUPPORTS_COMMENTS, AUTO_ADJUST_STRING_BUFFER
+        BUFFER_STRATEGY, MAX_STRING_LENGTH, BUFFER_LENGTH, SUPPORTS_COMMENTS, AUTO_ADJUST_STRING_BUFFER, ENCODING
     );
       
     private final int maxSize;
@@ -51,6 +53,7 @@ public class JsonParserFactoryImpl extends AbstractJsonFactory implements JsonPa
     private final BufferStrategy.BufferProvider<char[]> valueBufferProvider;
     private final boolean supportsComments;
     private final boolean autoAdjustBuffers;
+    private final Charset defaultEncoding;
 
     JsonParserFactoryImpl(final Map<String, ?> config) {
         super(config, SUPPORTED_CONFIG_KEYS, null);
@@ -65,9 +68,13 @@ public class JsonParserFactoryImpl extends AbstractJsonFactory implements JsonPa
         this.valueBufferProvider = getBufferProvider().newCharProvider(maxSize);
         this.supportsComments = getBool(SUPPORTS_COMMENTS, DEFAULT_SUPPORTS_COMMENT);
         this.autoAdjustBuffers = getBool(AUTO_ADJUST_STRING_BUFFER, true);
+        this.defaultEncoding = ofNullable(getString(ENCODING, null)).map(Charset::forName).orElse(null);
     }
 
     private JsonStreamParserImpl getDefaultJsonParserImpl(final InputStream in) {
+        if (defaultEncoding != null) {
+            return getDefaultJsonParserImpl(in, defaultEncoding);
+        }
         if (supportsComments) {
             return new CommentsJsonStreamParserImpl(in, maxSize, bufferProvider, valueBufferProvider, autoAdjustBuffers);
         }
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
index fd05752..bf4a2c0 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
@@ -21,8 +21,10 @@ package org.apache.johnzon.core;
 import javax.json.JsonException;
 import javax.json.stream.JsonLocation;
 import javax.json.stream.JsonParsingException;
+
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.Reader;
 import java.math.BigDecimal;
 import java.nio.charset.Charset;
@@ -149,8 +151,10 @@ public class JsonStreamParserImpl extends JohnzonJsonParserImpl implements JsonC
 
         if (reader != null) {
             this.in = reader;
-        } else {
-            this.in = new RFC4627AwareInputStreamReader(inputStream, encoding);
+        } else if (encoding != null) { // always respect it
+            this.in = new InputStreamReader(inputStream, encoding);
+        } else { // should we log the usage is unexpected? (for perf we want to avoid the pushbackinputstream)
+            this.in = new RFC4627AwareInputStreamReader(inputStream);
         }
     }
 
@@ -207,7 +211,7 @@ public class JsonStreamParserImpl extends JohnzonJsonParserImpl implements JsonC
         if (previousEvent != END_ARRAY && previousEvent != END_OBJECT &&
                 previousEvent != VALUE_STRING && previousEvent != VALUE_FALSE && previousEvent != VALUE_TRUE &&
                 previousEvent != VALUE_NULL && previousEvent != VALUE_NUMBER) {
-            if (bufferPos == Integer.MIN_VALUE) { // check we don't have an empty string to parse
+            if (bufferPos < 0) { // check we don't have an empty string to parse
                 final char c = readNextChar();
                 bufferPos--;
                 return c != EOF;
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/RFC4627AwareInputStreamReader.java b/johnzon-core/src/main/java/org/apache/johnzon/core/RFC4627AwareInputStreamReader.java
index 0fc2784..c3d0c37 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/RFC4627AwareInputStreamReader.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/RFC4627AwareInputStreamReader.java
@@ -29,15 +29,12 @@ import javax.json.JsonException;
 
 final class RFC4627AwareInputStreamReader extends InputStreamReader {
 
-    /**
-     * @param preferredCharset the Charset to use if no BOM is used. If {@code null} use UTF-8
-     */
-    RFC4627AwareInputStreamReader(final InputStream in, Charset preferredCharset) {
-        this(new PushbackInputStream(in,4), preferredCharset);
+    RFC4627AwareInputStreamReader(final InputStream in) {
+        this(new PushbackInputStream(in,4));
     }
 
-    private RFC4627AwareInputStreamReader(final PushbackInputStream in, Charset preferredCharset) {
-        super(in, getCharset(in, preferredCharset).newDecoder());
+    private RFC4627AwareInputStreamReader(final PushbackInputStream in) {
+        super(in, getCharset(in).newDecoder());
     }
 
     /**
@@ -86,8 +83,8 @@ final class RFC4627AwareInputStreamReader extends InputStreamReader {
 
         */
 
-    private static Charset getCharset(final PushbackInputStream inputStream, Charset preferredCharset) {
-        Charset charset = preferredCharset != null ? preferredCharset : StandardCharsets.UTF_8;
+    private static Charset getCharset(final PushbackInputStream inputStream) {
+        Charset charset = StandardCharsets.UTF_8;
         int bomLength=0;
         try {
             final byte[] utfBytes = readAllBytes(inputStream);
diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jaxrs/jsonb/jaxrs/JsonbJaxrsProvider.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jaxrs/jsonb/jaxrs/JsonbJaxrsProvider.java
index 30bf771..15e26fc 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jaxrs/jsonb/jaxrs/JsonbJaxrsProvider.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jaxrs/jsonb/jaxrs/JsonbJaxrsProvider.java
@@ -187,13 +187,13 @@ public class JsonbJaxrsProvider<T> implements MessageBodyWriter<T>, MessageBodyR
 
     @Override
     public T readFrom(final Class<T> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType,
-            final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws IOException, WebApplicationException {
+            final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws WebApplicationException {
         return getJsonb(type).fromJson(entityStream, genericType);
     }
 
     @Override
     public void writeTo(final T t, final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType,
-            final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws IOException, WebApplicationException {
+            final MultivaluedMap<String, Object> httpHeaders, final OutputStream entityStream) throws WebApplicationException {
         getJsonb(type).toJson(t, entityStream);
     }
 
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
index b05667c..6eadc0e 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
@@ -22,7 +22,7 @@ import static java.util.Arrays.asList;
 import static java.util.Collections.emptyMap;
 import static java.util.Locale.ROOT;
 
-import org.apache.johnzon.core.JsonParserFactoryImpl;
+// import org.apache.johnzon.core.JsonParserFactoryImpl; // don't depend on core in mapper
 import org.apache.johnzon.mapper.access.AccessMode;
 import org.apache.johnzon.mapper.access.BaseAccessMode;
 import org.apache.johnzon.mapper.access.FieldAccessMode;
@@ -158,7 +158,7 @@ public class MapperBuilder {
             }
             final Map<String, Object> config = new HashMap<String, Object>();
             if (bufferStrategy != null) {
-                config.put(JsonParserFactoryImpl.BUFFER_STRATEGY, bufferStrategy);
+                config.put("org.apache.johnzon.buffer-strategy", bufferStrategy);
             }
             if (pretty) {
                 config.put(JsonGenerator.PRETTY_PRINTING, true);
@@ -170,17 +170,20 @@ public class MapperBuilder {
 
             config.remove(JsonGenerator.PRETTY_PRINTING); // doesnt mean anything anymore for reader
             if (supportsComments) {
-                config.put(JsonParserFactoryImpl.SUPPORTS_COMMENTS, "true");
+                config.put("org.apache.johnzon.supports-comments", "true");
             }
             if (maxSize > 0) {
-                config.put(JsonParserFactoryImpl.MAX_STRING_LENGTH, maxSize);
+                config.put("org.apache.johnzon.max-string-length", maxSize);
             }
             if (bufferSize > 0) {
-                config.put(JsonParserFactoryImpl.BUFFER_LENGTH, bufferSize);
+                config.put("org.apache.johnzon.default-char-buffer", bufferSize);
             }
             if (autoAdjustStringBuffers) {
                 config.put("org.apache.johnzon.auto-adjust-buffer", true);
             }
+            if (encoding != null) {
+                config.put("org.apache.johnzon.encoding", encoding.name());
+            }
             if (readerFactory == null) {
                 readerFactory = provider.createReaderFactory(config);
             }
@@ -436,7 +439,7 @@ public class MapperBuilder {
     }
 
     public MapperBuilder setEncoding(final String encoding) {
-        this.encoding = Charset.forName(encoding);
+        this.encoding = encoding == null ? null : Charset.forName(encoding);
         return this;
     }