Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use locale passed to ObjectMapper configuration everywhere #2554

Closed
wants to merge 2 commits into from
Closed
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 @@ -393,6 +393,8 @@ public boolean useForType(JavaType t)
*/
protected final ConfigOverrides _configOverrides;

private Locale _locale = Locale.getDefault();

/*
/**********************************************************
/* Configuration settings: mix-in annotations
Expand Down Expand Up @@ -639,7 +641,7 @@ public ObjectMapper(JsonFactory jf,
* @since 2.5
*/
protected ClassIntrospector defaultClassIntrospector() {
return new BasicClassIntrospector();
return new BasicClassIntrospector(_locale);
}

/*
Expand Down Expand Up @@ -2085,6 +2087,7 @@ public InjectableValues getInjectableValues() {
* Default value used is {@link Locale#getDefault()}.
*/
public ObjectMapper setLocale(Locale l) {
_locale = l;
_deserializationConfig = _deserializationConfig.with(l);
_serializationConfig = _serializationConfig.with(l);
return this;
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -344,13 +344,13 @@ public boolean hasIgnorable(String name) {
* Method for constructing a {@link BeanDeserializer}, given all
* information collected.
*/
public JsonDeserializer<?> build()
public JsonDeserializer<?> build(Locale locale)
{
Collection<SettableBeanProperty> props = _properties.values();
_fixAccess(props);
BeanPropertyMap propertyMap = BeanPropertyMap.construct(props,
_config.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES),
_collectAliases(props));
_collectAliases(props), locale);
propertyMap.assignIndexes();

// view processing must be enabled if:
Expand Down Expand Up @@ -427,7 +427,7 @@ public JsonDeserializer<?> buildBuilderBased(JavaType valueType, String expBuild
_fixAccess(props);
BeanPropertyMap propertyMap = BeanPropertyMap.construct(props,
_config.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES),
_collectAliases(props));
_collectAliases(props), _context.getLocale());
propertyMap.assignIndexes();

boolean anyViews = !_config.isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ public JsonDeserializer<Object> buildBeanDeserializer(DeserializationContext ctx
if (type.isAbstract() && !valueInstantiator.canInstantiate()) {
deserializer = builder.buildAbstract();
} else {
deserializer = builder.build();
deserializer = builder.build(config.getLocale());
}
// may have modifier(s) that wants to modify or replace serializer we just built
// (note that `resolve()` and `createContextual()` called later on)
Expand Down Expand Up @@ -408,7 +408,7 @@ public JsonDeserializer<Object> buildThrowableDeserializer(DeserializationContex
builder = mod.updateBuilder(config, beanDesc, builder);
}
}
JsonDeserializer<?> deserializer = builder.build();
JsonDeserializer<?> deserializer = builder.build(config.getLocale());

/* At this point it ought to be a BeanDeserializer; if not, must assume
* it's some other thing that can handle deserialization ok...
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,19 @@ public class BeanPropertyMap
*/
private final Map<String,String> _aliasMapping;

private final Locale _locale;

/**
* @since 2.9
*/
public BeanPropertyMap(boolean caseInsensitive, Collection<SettableBeanProperty> props,
Map<String,List<PropertyName>> aliasDefs)
Map<String,List<PropertyName>> aliasDefs, Locale locale)
{
_caseInsensitive = caseInsensitive;
_propsInOrder = props.toArray(new SettableBeanProperty[props.size()]);
_aliasDefs = aliasDefs;
_aliasMapping = _buildAliasMapping(aliasDefs);
_locale = locale;
init(props);
}

Expand All @@ -94,7 +97,7 @@ public BeanPropertyMap(boolean caseInsensitive, Collection<SettableBeanProperty>
* @since 2.9.6
*/
private BeanPropertyMap(BeanPropertyMap src,
SettableBeanProperty newProp, int hashIndex, int orderedIndex)
SettableBeanProperty newProp, int hashIndex, int orderedIndex, Locale locale)
{
// First, copy most fields as is:
_caseInsensitive = src._caseInsensitive;
Expand All @@ -109,14 +112,15 @@ private BeanPropertyMap(BeanPropertyMap src,
_propsInOrder = Arrays.copyOf(src._propsInOrder, src._propsInOrder.length);
_hashArea[hashIndex] = newProp;
_propsInOrder[orderedIndex] = newProp;
_locale = locale;
}

/* Copy constructors used when a property needs to be appended (can't replace)
*
* @since 2.9.6
*/
private BeanPropertyMap(BeanPropertyMap src,
SettableBeanProperty newProp, String key, int slot)
SettableBeanProperty newProp, String key, int slot, Locale locale)
{
// First, copy most fields as is:
_caseInsensitive = src._caseInsensitive;
Expand Down Expand Up @@ -151,25 +155,28 @@ private BeanPropertyMap(BeanPropertyMap src,
}
_hashArea[ix] = key;
_hashArea[ix+1] = newProp;
_locale = locale;
}

@Deprecated // since 2.8
public BeanPropertyMap(boolean caseInsensitive, Collection<SettableBeanProperty> props)
{
this(caseInsensitive, props, Collections.<String,List<PropertyName>>emptyMap());
//TODO what to do here? can I change the constructor even though it's deprecated?
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What to do here? can I change the constructor even though it's deprecated?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Odd, 3.0 should not have any deprecated ones, must have leaked via merge from 2.x (where addition of new constructor does lead to marking of old ones as deprecated). Signatures of deprecated methods should not be changed in most cases as they are strictly left for backwards compatibility (for old code that is compiled to access them).
But at the same time, deprecated methods need not support new features so using bogus (or default) Locale would be fine.

this(caseInsensitive, props, Collections.<String,List<PropertyName>>emptyMap(), Locale.getDefault());
}

/**
* @since 2.8
*/
protected BeanPropertyMap(BeanPropertyMap base, boolean caseInsensitive)
protected BeanPropertyMap(BeanPropertyMap base, boolean caseInsensitive, Locale locale)
{
_caseInsensitive = caseInsensitive;
_aliasDefs = base._aliasDefs;
_aliasMapping = base._aliasMapping;

// 16-May-2016, tatu: Alas, not enough to just change flag, need to re-init as well.
_propsInOrder = Arrays.copyOf(base._propsInOrder, base._propsInOrder.length);
_locale = locale;
init(Arrays.asList(_propsInOrder));
}

Expand All @@ -184,7 +191,7 @@ public BeanPropertyMap withCaseInsensitivity(boolean state) {
if (_caseInsensitive == state) {
return this;
}
return new BeanPropertyMap(this, state);
return new BeanPropertyMap(this, state, _locale);
}

protected void init(Collection<SettableBeanProperty> props)
Expand Down Expand Up @@ -252,14 +259,14 @@ private final static int findSize(int size)
* @since 2.6
*/
public static BeanPropertyMap construct(Collection<SettableBeanProperty> props,
boolean caseInsensitive, Map<String,List<PropertyName>> aliasMapping) {
return new BeanPropertyMap(caseInsensitive, props, aliasMapping);
boolean caseInsensitive, Map<String,List<PropertyName>> aliasMapping, Locale locale) {
return new BeanPropertyMap(caseInsensitive, props, aliasMapping, locale);
}

@Deprecated // since 2.9
public static BeanPropertyMap construct(Collection<SettableBeanProperty> props, boolean caseInsensitive) {
public static BeanPropertyMap construct(Collection<SettableBeanProperty> props, boolean caseInsensitive, Locale locale) {
return construct(props, caseInsensitive,
Collections.<String,List<PropertyName>>emptyMap());
Collections.<String,List<PropertyName>>emptyMap(), locale);
}

/**
Expand All @@ -277,13 +284,13 @@ public BeanPropertyMap withProperty(SettableBeanProperty newProp)
for (int i = 1, end = _hashArea.length; i < end; i += 2) {
SettableBeanProperty prop = (SettableBeanProperty) _hashArea[i];
if ((prop != null) && prop.getName().equals(key)) {
return new BeanPropertyMap(this, newProp, i, _findFromOrdered(prop));
return new BeanPropertyMap(this, newProp, i, _findFromOrdered(prop), _locale);
}
}
// If not, append
final int slot = _hashCode(key);

return new BeanPropertyMap(this, newProp, key, slot);
return new BeanPropertyMap(this, newProp, key, slot, _locale);
}

public BeanPropertyMap assignIndexes()
Expand Down Expand Up @@ -324,7 +331,7 @@ public BeanPropertyMap renameAll(NameTransformer transformer)
}
// should we try to re-index? Ordering probably changed but caller probably doesn't want changes...
// 26-Feb-2017, tatu: Probably SHOULD handle renaming wrt Aliases?
return new BeanPropertyMap(_caseInsensitive, newProps, _aliasDefs);
return new BeanPropertyMap(_caseInsensitive, newProps, _aliasDefs, _locale);
}

/*
Expand Down Expand Up @@ -360,7 +367,7 @@ public BeanPropertyMap withoutProperties(Collection<String> toExclude)
}
}
// should we try to re-index? Apparently no need
return new BeanPropertyMap(_caseInsensitive, newProps, _aliasDefs);
return new BeanPropertyMap(_caseInsensitive, newProps, _aliasDefs, _locale);
}

@Deprecated // in 2.9.4 -- must call method that takes old and new property to avoid mismatch
Expand Down Expand Up @@ -490,7 +497,7 @@ public SettableBeanProperty[] getPropertiesInInsertionOrder() {
// Confining this case insensitivity to this function (and the find method) in case we want to
// apply a particular locale to the lower case function. For now, using the default.
protected final String getPropertyName(SettableBeanProperty prop) {
return _caseInsensitive ? prop.getName().toLowerCase() : prop.getName();
return _caseInsensitive ? prop.getName().toLowerCase(_locale) : prop.getName();
}

/*
Expand Down Expand Up @@ -521,7 +528,7 @@ public SettableBeanProperty find(String key)
throw new IllegalArgumentException("Cannot pass null property name");
}
if (_caseInsensitive) {
key = key.toLowerCase();
key = key.toLowerCase(_locale);
}

// inlined `_hashCode(key)`
Expand Down Expand Up @@ -779,12 +786,12 @@ private Map<String,String> _buildAliasMapping(Map<String,List<PropertyName>> def
for (Map.Entry<String,List<PropertyName>> entry : defs.entrySet()) {
String key = entry.getKey();
if (_caseInsensitive) {
key = key.toLowerCase();
key = key.toLowerCase(_locale);
}
for (PropertyName pn : entry.getValue()) {
String mapped = pn.getSimpleName();
if (_caseInsensitive) {
mapped = mapped.toLowerCase();
mapped = mapped.toLowerCase(_locale);
}
aliases.put(mapped, key);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ protected PropertyBasedCreator(DeserializationContext ctxt,
{
_valueInstantiator = valueInstantiator;
if (caseInsensitive) {
_propertyLookup = new CaseInsensitiveMap();
_propertyLookup = new CaseInsensitiveMap(ctxt.getLocale());
} else {
_propertyLookup = new HashMap<String, SettableBeanProperty>();
}
Expand Down Expand Up @@ -225,15 +225,20 @@ public Object build(DeserializationContext ctxt, PropertyValueBuffer buffer) thr
static class CaseInsensitiveMap extends HashMap<String, SettableBeanProperty>
{
private static final long serialVersionUID = 1L;
private final Locale locale;

CaseInsensitiveMap(Locale locale) {
this.locale = locale;
}

@Override
public SettableBeanProperty get(Object key0) {
return super.get(((String) key0).toLowerCase());
return super.get(((String) key0).toLowerCase(locale));
}

@Override
public SettableBeanProperty put(String key, SettableBeanProperty value) {
key = key.toLowerCase();
key = key.toLowerCase(locale);
return super.put(key, value);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.fasterxml.jackson.databind.introspect;

import java.util.Collection;
import java.util.Locale;
import java.util.Map;

import com.fasterxml.jackson.databind.AnnotationIntrospector;
Expand Down Expand Up @@ -57,18 +58,21 @@ public class BasicClassIntrospector
AnnotatedClassResolver.createPrimordial(CLS_OBJECT));
}

private final Locale _locale;

/*
/**********************************************************
/* Life cycle
/**********************************************************
*/

public BasicClassIntrospector() {
public BasicClassIntrospector(Locale locale) {
_locale = locale;
}

@Override
public ClassIntrospector copy() {
return new BasicClassIntrospector();
return new BasicClassIntrospector(_locale);
}

/*
Expand Down Expand Up @@ -195,7 +199,7 @@ protected POJOPropertiesCollector collectPropertiesWithBuilder(MapperConfig<?> c
protected POJOPropertiesCollector constructPropertyCollector(MapperConfig<?> config,
AnnotatedClass ac, JavaType type, boolean forSerialization, String mutatorPrefix)
{
return new POJOPropertiesCollector(config, forSerialization, type, ac, mutatorPrefix);
return new POJOPropertiesCollector(config, forSerialization, type, ac, mutatorPrefix, _locale);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public class POJOPropertiesCollector
* but differs for builder objects ("with" by default).
*/
protected final String _mutatorPrefix;

private final Locale _locale;

/*
/**********************************************************
Expand Down Expand Up @@ -124,14 +126,15 @@ public class POJOPropertiesCollector
*/

protected POJOPropertiesCollector(MapperConfig<?> config, boolean forSerialization,
JavaType type, AnnotatedClass classDef, String mutatorPrefix)
JavaType type, AnnotatedClass classDef, String mutatorPrefix, Locale locale)
{
_config = config;
_stdBeanNaming = config.isEnabled(MapperFeature.USE_STD_BEAN_NAMING);
_forSerialization = forSerialization;
_type = type;
_classDef = classDef;
_mutatorPrefix = (mutatorPrefix == null) ? "set" : mutatorPrefix;
_locale = locale;
if (config.isAnnotationProcessingEnabled()) {
_useAnnotations = true;
_annotationIntrospector = _config.getAnnotationIntrospector();
Expand Down Expand Up @@ -845,22 +848,22 @@ protected void _renameUsing(Map<String, POJOPropertyBuilder> propMap,
if (!prop.isExplicitlyNamed() || _config.isEnabled(MapperFeature.ALLOW_EXPLICIT_PROPERTY_RENAMING)) {
if (_forSerialization) {
if (prop.hasGetter()) {
rename = naming.nameForGetterMethod(_config, prop.getGetter(), fullName.getSimpleName());
rename = naming.nameForGetterMethod(_config, prop.getGetter(), fullName.getSimpleName(), _locale);
} else if (prop.hasField()) {
rename = naming.nameForField(_config, prop.getField(), fullName.getSimpleName());
rename = naming.nameForField(_config, prop.getField(), fullName.getSimpleName(), _locale);
}
} else {
if (prop.hasSetter()) {
rename = naming.nameForSetterMethod(_config, prop.getSetter(), fullName.getSimpleName());
rename = naming.nameForSetterMethod(_config, prop.getSetter(), fullName.getSimpleName(), _locale);
} else if (prop.hasConstructorParameter()) {
rename = naming.nameForConstructorParameter(_config, prop.getConstructorParameter(), fullName.getSimpleName());
rename = naming.nameForConstructorParameter(_config, prop.getConstructorParameter(), fullName.getSimpleName(), _locale);
} else if (prop.hasField()) {
rename = naming.nameForField(_config, prop.getField(), fullName.getSimpleName());
rename = naming.nameForField(_config, prop.getField(), fullName.getSimpleName(), _locale);
} else if (prop.hasGetter()) {
/* Plus, when getter-as-setter is used, need to convert that too..
* (should we verify that's enabled? For now, assume it's ok always)
*/
rename = naming.nameForGetterMethod(_config, prop.getGetter(), fullName.getSimpleName());
rename = naming.nameForGetterMethod(_config, prop.getGetter(), fullName.getSimpleName(), _locale);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

//TODO what to do here
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how to approach this one. We can't really pass the locale here.
But at the same time it's not causing (known) problems yet

public enum JsonFormatTypes
{
STRING,
Expand Down
Loading