Skip to content

Commit

Permalink
Fix #50
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Apr 14, 2017
1 parent 896d2c7 commit 47b46e4
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,8 @@ public final boolean isDisabled(int flags) {
public final boolean isEnabled(int flags) {
return (flags & _mask) != 0;
}
}
}

// Important: has to come before 'std' instance, since it refers to it
private final static int DEFAULT_FEATURES = Feature.defaults();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,14 @@ public Map<Object,Object> readFromObject(JSONReader r, JsonParser p, MapBuilder
}

// but then it's loop-de-loop
b = b.start().put(key, value);
do {
b = b.put(fromKey(p.getCurrentName()), read(r, p));
} while (p.nextValue() != JsonToken.END_OBJECT);
try {
b = b.start().put(key, value);
do {
b = b.put(fromKey(p.getCurrentName()), read(r, p));
} while (p.nextValue() != JsonToken.END_OBJECT);
} catch (IllegalArgumentException e) {
throw JSONObjectException.from(p, e.getMessage());
}
return b.build();
}

Expand All @@ -117,11 +121,15 @@ public Object[] readArrayFromArray(JSONReader r, JsonParser p, CollectionBuilder
if (p.nextToken() == JsonToken.END_ARRAY) {
return b.singletonArray(value);
}
b = b.start().add(value);
do {
b = b.add(read(r, p));
} while (p.nextToken() != JsonToken.END_ARRAY);
return b.buildArray();
try {
b = b.start().add(value);
do {
b = b.add(read(r, p));
} while (p.nextToken() != JsonToken.END_ARRAY);
return b.buildArray();
} catch (IllegalArgumentException e) {
throw JSONObjectException.from(p, e.getMessage());
}
}

public Collection<Object> readCollectionFromArray(JSONReader r, JsonParser p, CollectionBuilder b) throws IOException
Expand All @@ -133,11 +141,15 @@ public Collection<Object> readCollectionFromArray(JSONReader r, JsonParser p, Co
if (p.nextToken() == JsonToken.END_ARRAY) {
return b.singletonCollection(value);
}
b = b.start().add(value);
do {
b = b.add(read(r, p));
} while (p.nextToken() != JsonToken.END_ARRAY);
return b.buildCollection();
try {
b = b.start().add(value);
do {
b = b.add(read(r, p));
} while (p.nextToken() != JsonToken.END_ARRAY);
return b.buildCollection();
} catch (IllegalArgumentException e) {
throw JSONObjectException.from(p, e.getMessage());
}
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import com.fasterxml.jackson.jr.ob.JSON;
import com.fasterxml.jackson.jr.ob.JSON.Feature;
import com.fasterxml.jackson.jr.ob.JSONObjectException;

/**
* Helper class that is used for constructing {@link java.util.Map}s
Expand All @@ -18,7 +19,8 @@
public abstract class MapBuilder
{
protected final int _features;

protected final boolean _checkDups;

/**
* Optional {@link Map} implementation class, used when specific
* implementation is desired.
Expand All @@ -27,6 +29,7 @@ public abstract class MapBuilder

protected MapBuilder(int features, Class<?> type) {
_features = features;
_checkDups = JSON.Feature.FAIL_ON_DUPLICATE_MAP_KEYS.isEnabled(features);
_mapType = type;
}

Expand Down Expand Up @@ -67,7 +70,7 @@ public final boolean isEnabled(JSON.Feature f) {
*</pre>
* which assumes that a builder has been constructed with {@link #newBuilder}
*/
public Map<Object,Object> emptyMap() {
public Map<Object,Object> emptyMap() throws JSONObjectException {
return start().build();
}

Expand All @@ -81,7 +84,7 @@ public Map<Object,Object> emptyMap() {
* start().put(key, value).build();
*</pre>
*/
public Map<Object,Object> singletonMap(Object key, Object value) {
public Map<Object,Object> singletonMap(Object key, Object value) throws JSONObjectException {
return start().put(key, value).build();
}

Expand All @@ -102,7 +105,7 @@ public Map<Object,Object> singletonMap(Object key, Object value) {
public static class Default extends MapBuilder
{
protected Map<Object,Object> _current;

protected Default(int features, Class<?> type) {
super(features, type);
}
Expand All @@ -116,7 +119,7 @@ public MapBuilder newBuilder(int features) {
public MapBuilder newBuilder(Class<?> mapImpl) {
return new Default(_features, mapImpl);
}

@Override
public MapBuilder start() {
// If this builder is "busy", create a new one...
Expand All @@ -126,7 +129,7 @@ public MapBuilder start() {
_current = _map(12);
return this;
}

@Override
public Map<Object,Object> build() {
Map<Object,Object> result = _current;
Expand All @@ -136,10 +139,17 @@ public Map<Object,Object> build() {

@Override
public MapBuilder put(Object key, Object value) {
if (_checkDups) {
if (_current.containsKey(key)) {
// 14-Apr-2017, tatu: Note that choice of `IllegalArgumentException` is arbitrary
// but not random: caller catches and re-packages it to give context
throw new IllegalArgumentException("Duplicate key (key '"+key+"')");
}
}
_current.put(key, value);
return this;
}

@Override
public Map<Object,Object> emptyMap() {
if ((_mapType == null) && isEnabled(Feature.READ_ONLY)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,23 @@ public Object readNext(JSONReader r, JsonParser p) throws IOException {
}
throw _reportProblem(p);
}
b = b.start().put(propName0, value);
while (true) {
b = b.put(propName, _valueReader.readNext(r, p));
propName = p.nextFieldName();
if (propName == null) {
if (p.hasToken(JsonToken.END_OBJECT)) {
return b.build();
try {
b = b.start().put(propName0, value);
while (true) {
b = b.put(propName, _valueReader.readNext(r, p));
propName = p.nextFieldName();
if (propName == null) {
if (p.hasToken(JsonToken.END_OBJECT)) {
return b.build();
}
throw _reportProblem(p);
}
throw _reportProblem(p);
}
} catch (IllegalArgumentException e) {
throw JSONObjectException.from(p, e.getMessage());
}
}

@Override
public Object read(JSONReader r, JsonParser p) throws IOException {
MapBuilder b = r._mapBuilder(_mapType);
Expand All @@ -77,20 +81,24 @@ public Object read(JSONReader r, JsonParser p) throws IOException {
}
throw _reportProblem(p);
}
b = b.start().put(propName0, value);
while (true) {
b = b.put(propName, _valueReader.readNext(r, p));
propName = p.nextFieldName();
if (propName == null) {
if (p.hasToken(JsonToken.END_OBJECT)) {
return b.build();
try {
b = b.start().put(propName0, value);
while (true) {
b = b.put(propName, _valueReader.readNext(r, p));
propName = p.nextFieldName();
if (propName == null) {
if (p.hasToken(JsonToken.END_OBJECT)) {
return b.build();
}
throw _reportProblem(p);
}
throw _reportProblem(p);
}
} catch (IllegalArgumentException e) {
throw JSONObjectException.from(p, e.getMessage());
}
}

protected IOException _reportProblem(JsonParser p) {
protected JSONObjectException _reportProblem(JsonParser p) {
return JSONObjectException.from(p, "Unexpected token "+p.getCurrentToken()+"; should get FIELD_NAME or END_OBJECT");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,17 @@ public void testPojoWithIsGetter() throws Exception
.asString(new IsBean());
assertEquals(aposToQuotes("{'value':42}"), json);
}

public void testFailOnDupMapKeys() throws Exception
{
JSON j = JSON.std.with(JSON.Feature.FAIL_ON_DUPLICATE_MAP_KEYS);
assertTrue(j.isEnabled(JSON.Feature.FAIL_ON_DUPLICATE_MAP_KEYS));
final String json = "{\"a\":1,\"b\":2,\"b\":3,\"c\":4}";
try {
/*Map<?,?> map =*/ j.mapFrom(json);
fail("Should not pass");
} catch (JSONObjectException e) {
verifyException(e, "Duplicate key");
}
}
}
5 changes: 5 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Project: jackson-jr
=== Releases ===
------------------------------------------------------------------------

2.8.9 (not yet released)

#50: Duplicate key detection does not work
(reported by inorick@github)

2.8.8 (05-Apr-2017)
2.8.7 (21-Feb-2017)
2.8.6 (12-Jan-2017)
Expand Down

0 comments on commit 47b46e4

Please sign in to comment.