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 <rmannibu...@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; }