Skip to content
40 changes: 40 additions & 0 deletions src/main/java/tools/jackson/databind/ObjectMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;

Expand Down Expand Up @@ -2230,6 +2231,45 @@ public ObjectReader readerForMapOf(Class<?> type) {
null, _injectableValues);
}

/**
* Factory method for constructing {@link ObjectReader} that will
* read or update instances of auto-detected type; inferred from compiled
* info. Note that the nominal parameter MUST be an empty array;
* otherwise an exception will be thrown.
* Usage:
*<pre>
* MyType result = objectMapper.readerForDetectedType().readValue(json);
*</pre>
*
* @since 3.0
*/
public <T> ObjectReader readerForDetectedType(T... reified) {
// Should be auto-generated empty array; verify
Objects.requireNonNull(reified, "reified");
if (reified.length != 0) {
throw new IllegalArgumentException(String.format(
"argument \reified\" should be empty; has %d elements", reified.length));
}
Type type = _getClassOf(reified);
System.err.println("DEBUG: reified type: "+type);
_assertNotNull("type", type);
return _newReader(deserializationConfig(), _typeFactory.constructType(type), null,
null, _injectableValues);
}

/**
* Utility method to get the class type from a varargs array.
*
* @param <T> the generic type
* @param array the varargs array
* @return the class of the array component
*
* @since 3.0
*/
private static <T> Class<T> _getClassOf(T[] array) {
return (Class<T>) array.getClass().getComponentType();
}

/**
* Factory method for constructing {@link ObjectReader} that will
* use specified {@link JsonNodeFactory} for constructing JSON trees.
Expand Down
27 changes: 25 additions & 2 deletions src/test/java/tools/jackson/databind/ObjectReaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void testReaderForArrayOf() throws Exception
assertEquals(ABC.C, abcs[1]);
}

// [databind#2693]: convenience read methods:
// [databind#2693]: convenience read methods
@Test
public void testReaderForListOf() throws Exception
{
Expand All @@ -100,7 +100,7 @@ public void testReaderForListOf() throws Exception
assertEquals(Arrays.asList(ABC.B, ABC.C), value);
}

// [databind#2693]: convenience read methods:
// [databind#2693]: convenience read methods
@Test
public void testReaderForMapOf() throws Exception
{
Expand All @@ -110,6 +110,29 @@ public void testReaderForMapOf() throws Exception
assertEquals(Collections.singletonMap("key", ABC.B), value);
}

// [databind#5064]: auto-detection of type
@Test
public void testReaderForDetectedType() throws Exception
{
// First, regular "untyped" (java.lang.Object)
List<Integer> ob = MAPPER.readerForDetectedType()
.readValue("[1]");
assertNotNull(ob);
assertEquals(1, ob.get(0));

// then simple pojo
Point point = MAPPER.readerForDetectedType().readValue("{\"x\":1,\"y\":2}");
assertNotNull(point);
assertEquals(1, point.x);
assertEquals(2, point.y);

// and more complex
POJO pojo = MAPPER.readerForDetectedType().readValue("{\"name\":{\"value\":123}}");
assertNotNull(pojo);
assertNotNull(pojo.name);
assertEquals(Map.of("value", 123), pojo.name);
}

/*
/**********************************************************
/* Test methods, some alternative JSON settings
Expand Down
Loading