Skip to content

Commit

Permalink
Fix #2416
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Aug 7, 2019
1 parent 985ee58 commit 9577138
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 66 deletions.
1 change: 1 addition & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Project: jackson-databind
(reported by andreasbaus@github)
#2393: `TreeTraversingParser.getLongValue()` incorrectly checks `canConvertToInt()`
(reported by RabbidDog@github)
#2416: Optimize `ValueInstantiator` construction for default `Collection`, `Map` types

2.10.0.pr1 (19-Jul-2019)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonCreator.Mode;

import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.core.JsonParser;

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.cfg.DeserializerFactoryConfig;
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
import com.fasterxml.jackson.databind.deser.impl.CreatorCandidate;
import com.fasterxml.jackson.databind.deser.impl.CreatorCollector;
import com.fasterxml.jackson.databind.deser.impl.JDKValueInstantiators;
import com.fasterxml.jackson.databind.deser.impl.JavaUtilCollectionsDeserializers;
import com.fasterxml.jackson.databind.deser.std.*;
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
Expand Down Expand Up @@ -216,7 +216,7 @@ public ValueInstantiator findValueInstantiator(DeserializationContext ctxt,
if (instantiator == null) {
// Second: see if some of standard Jackson/JDK types might provide value
// instantiators.
instantiator = _findStdValueInstantiator(config, beanDesc);
instantiator = JDKValueInstantiators.findStdValueInstantiator(config, beanDesc.getBeanClass());
if (instantiator == null) {
instantiator = _constructDefaultValueInstantiator(ctxt, beanDesc);
}
Expand Down Expand Up @@ -246,30 +246,6 @@ public ValueInstantiator findValueInstantiator(DeserializationContext ctxt,
return instantiator;
}

private ValueInstantiator _findStdValueInstantiator(DeserializationConfig config,
BeanDescription beanDesc)
throws JsonMappingException
{
Class<?> raw = beanDesc.getBeanClass();
if (raw == JsonLocation.class) {
return new JsonLocationInstantiator();
}
// [databind#1868]: empty List/Set/Map
if (Collection.class.isAssignableFrom(raw)) {
if (Collections.EMPTY_SET.getClass() == raw) {
return new ConstantValueInstantiator(Collections.EMPTY_SET);
}
if (Collections.EMPTY_LIST.getClass() == raw) {
return new ConstantValueInstantiator(Collections.EMPTY_LIST);
}
} else if (Map.class.isAssignableFrom(raw)) {
if (Collections.EMPTY_MAP.getClass() == raw) {
return new ConstantValueInstantiator(Collections.EMPTY_MAP);
}
}
return null;
}

/**
* Method that will construct standard default {@link ValueInstantiator}
* using annotations (like @JsonCreator) and visibility rules
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,10 @@ public interface Gettable {
* to be used instead of directly extending {@link ValueInstantiator} itself.
*/
public static class Base extends ValueInstantiator
implements java.io.Serializable // just because used as base for "standard" variants
{
private static final long serialVersionUID = 1L;

protected final Class<?> _valueType;

public Base(Class<?> type) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package com.fasterxml.jackson.databind.deser.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.ValueInstantiator;
import com.fasterxml.jackson.databind.deser.std.JsonLocationInstantiator;

/**
* Container for a set of {@link ValueInstantiator}s used for certain critical
* JDK value types, either as performance optimization for initialization time observed
* by profiling, or due to difficulty in otherwise finding constructors.
*
* @since 2.10
*/
public abstract class JDKValueInstantiators
{
public static ValueInstantiator findStdValueInstantiator(DeserializationConfig config,
Class<?> raw)
{
if (raw == JsonLocation.class) {
return new JsonLocationInstantiator();
}
// [databind#1868]: empty List/Set/Map
if (Collection.class.isAssignableFrom(raw)) {
if (raw == ArrayList.class) {
return ArrayListInstantiator.INSTANCE;
}
// [databind#XXX]: optimize commonly needed default creators
if (Collections.EMPTY_SET.getClass() == raw) {
return new ConstantValueInstantiator(Collections.EMPTY_SET);
}
if (Collections.EMPTY_LIST.getClass() == raw) {
return new ConstantValueInstantiator(Collections.EMPTY_LIST);
}
} else if (Map.class.isAssignableFrom(raw)) {
if (raw == LinkedHashMap.class) {
return LinkedHashMapInstantiator.INSTANCE;
}
if (Collections.EMPTY_MAP.getClass() == raw) {
return new ConstantValueInstantiator(Collections.EMPTY_MAP);
}
}
return null;
}

private static class ArrayListInstantiator
extends ValueInstantiator.Base
implements java.io.Serializable
{
private static final long serialVersionUID = 2L;

public final static ArrayListInstantiator INSTANCE = new ArrayListInstantiator();
public ArrayListInstantiator() {
super(ArrayList.class);
}

@Override
public boolean canInstantiate() { return true; }

@Override
public boolean canCreateUsingDefault() { return true; }

@Override
public Object createUsingDefault(DeserializationContext ctxt) throws IOException {
return new ArrayList<>();
}
}

private static class LinkedHashMapInstantiator
extends ValueInstantiator.Base
implements java.io.Serializable
{
private static final long serialVersionUID = 2L;

public final static LinkedHashMapInstantiator INSTANCE = new LinkedHashMapInstantiator();

public LinkedHashMapInstantiator() {
super(LinkedHashMap.class);
}

@Override
public boolean canInstantiate() { return true; }

@Override
public boolean canCreateUsingDefault() { return true; }

@Override
public Object createUsingDefault(DeserializationContext ctxt) throws IOException {
return new LinkedHashMap<>();
}
}

private static class ConstantValueInstantiator
extends ValueInstantiator.Base
implements java.io.Serializable
{
private static final long serialVersionUID = 2L;

protected final Object _value;

public ConstantValueInstantiator(Object value) {
super(value.getClass());
_value = value;
}

@Override // yes, since default ctor works
public boolean canInstantiate() { return true; }

@Override
public boolean canCreateUsingDefault() { return true; }

@Override
public Object createUsingDefault(DeserializationContext ctxt) throws IOException {
return _value;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,7 @@ public BasicBeanDescription forCreation(DeserializationConfig cfg,
{
BasicBeanDescription desc = _findStdTypeDesc(type);
if (desc == null) {

// As per [Databind#550], skip full introspection for some of standard
// As per [databind#550], skip full introspection for some of standard
// structured types as well
desc = _findStdJdkCollectionDesc(cfg, type);
if (desc == null) {
Expand Down

This file was deleted.

0 comments on commit 9577138

Please sign in to comment.