diff options
author | Tatu Saloranta <tatu.saloranta@iki.fi> | 2014-03-14 20:10:36 -0700 |
---|---|---|
committer | Tatu Saloranta <tatu.saloranta@iki.fi> | 2014-03-14 20:10:36 -0700 |
commit | fdf3a9143b82b61140602f2f1c1090a3cd28ffd5 (patch) | |
tree | e6891b3a9f2fb6787d1803985772c9c414bfe456 /src/main/java/com | |
parent | 02a63940c14cab516e185d289185fdde468e4e80 (diff) | |
download | jackson-databind-fdf3a9143b82b61140602f2f1c1090a3cd28ffd5.tar.gz |
refactoring handling of forward-references
Diffstat (limited to 'src/main/java/com')
5 files changed, 70 insertions, 74 deletions
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/SettableAnyProperty.java b/src/main/java/com/fasterxml/jackson/databind/deser/SettableAnyProperty.java index 29b465ca6..3cce67642 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/SettableAnyProperty.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/SettableAnyProperty.java @@ -113,8 +113,8 @@ public class SettableAnyProperty if (!(_valueDeserializer.getObjectIdReader() != null)) { throw JsonMappingException.from(jp, "Unresolved forward reference but no identity info.", reference); } - AnySetterReferring referring = new AnySetterReferring(instance, propName, reference.getUnresolvedId(), - reference.getLocation()); + AnySetterReferring referring = new AnySetterReferring(this, reference, + _type.getRawClass(), instance, propName); reference.getRoid().appendReferring(referring); } } @@ -187,28 +187,29 @@ public class SettableAnyProperty @Override public String toString() { return "[any property on class "+getClassName()+"]"; } - private class AnySetterReferring extends Referring { - private Object _pojo; - private String _propName; - private Object _unresolvedId; + private static class AnySetterReferring extends Referring { + private final SettableAnyProperty _parent; + private final Object _pojo; + private final String _propName; - public AnySetterReferring(Object instance, String propName, Object id, JsonLocation location) + public AnySetterReferring(SettableAnyProperty parent, + UnresolvedForwardReference reference, Class<?> type, Object instance, String propName) { - super(location, _type.getRawClass()); + super(reference, type); + _parent = parent; _pojo = instance; _propName = propName; - _unresolvedId = id; } @Override public void handleResolvedForwardReference(Object id, Object value) throws IOException { - if (!id.equals(_unresolvedId)) { + if (!hasId(id)) { throw new IllegalArgumentException("Trying to resolve a forward reference with id [" + id.toString() + "] that wasn't previously registered."); } - set(_pojo, _propName, value); + _parent.set(_pojo, _propName, value); } } diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/impl/ObjectIdReferenceProperty.java b/src/main/java/com/fasterxml/jackson/databind/deser/impl/ObjectIdReferenceProperty.java index a45dbf1d9..08426e099 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/impl/ObjectIdReferenceProperty.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/impl/ObjectIdReferenceProperty.java @@ -3,7 +3,6 @@ package com.fasterxml.jackson.databind.deser.impl; import java.io.IOException; import java.lang.annotation.Annotation; -import com.fasterxml.jackson.core.JsonLocation; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; @@ -42,26 +41,22 @@ public class ObjectIdReferenceProperty extends SettableBeanProperty { } @Override - public SettableBeanProperty withValueDeserializer(JsonDeserializer<?> deser) - { + public SettableBeanProperty withValueDeserializer(JsonDeserializer<?> deser) { return new ObjectIdReferenceProperty(this, deser); } @Override - public SettableBeanProperty withName(PropertyName newName) - { + public SettableBeanProperty withName(PropertyName newName) { return new ObjectIdReferenceProperty(this, newName); } @Override - public <A extends Annotation> A getAnnotation(Class<A> acls) - { + public <A extends Annotation> A getAnnotation(Class<A> acls) { return _forward.getAnnotation(acls); } @Override - public AnnotatedMember getMember() - { + public AnnotatedMember getMember() { return _forward.getMember(); } @@ -83,8 +78,7 @@ public class ObjectIdReferenceProperty extends SettableBeanProperty { if (!usingIdentityInfo) { throw JsonMappingException.from(jp, "Unresolved forward reference but no identity info.", reference); } - reference.getRoid().appendReferring( - new PropertyReferring(instance, reference.getUnresolvedId(), reference.getLocation())); + reference.getRoid().appendReferring(new PropertyReferring(this, reference, _type.getRawClass(), instance)); return null; } } @@ -103,26 +97,27 @@ public class ObjectIdReferenceProperty extends SettableBeanProperty { return _forward.setAndReturn(instance, value); } - public final class PropertyReferring extends Referring { + public final static class PropertyReferring extends Referring { + private final ObjectIdReferenceProperty _parent; public final Object _pojo; - private Object _unresolvedId; - public PropertyReferring(Object ob, Object id, JsonLocation location) + public PropertyReferring(ObjectIdReferenceProperty parent, + UnresolvedForwardReference ref, Class<?> type, Object ob) { - super(location, _type.getRawClass()); + super(ref, type); + _parent = parent; _pojo = ob; - _unresolvedId = id; } @Override public void handleResolvedForwardReference(Object id, Object value) throws IOException { - if (!id.equals(_unresolvedId)) { + if (!hasId(id)) { throw new IllegalArgumentException("Trying to resolve a forward reference with id [" + id + "] that wasn't previously seen as unresolved."); } - set(_pojo, value); + _parent.set(_pojo, value); } } } diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/impl/ReadableObjectId.java b/src/main/java/com/fasterxml/jackson/databind/deser/impl/ReadableObjectId.java index 82c501d73..812c5660e 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/impl/ReadableObjectId.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/impl/ReadableObjectId.java @@ -8,6 +8,7 @@ import java.util.LinkedList; import com.fasterxml.jackson.annotation.ObjectIdGenerator.IdKey; import com.fasterxml.jackson.annotation.ObjectIdResolver; import com.fasterxml.jackson.core.JsonLocation; +import com.fasterxml.jackson.databind.deser.UnresolvedForwardReference; /** * Simple value container for containing information about single Object Id @@ -99,19 +100,20 @@ public class ReadableObjectId */ public static abstract class Referring { - private final JsonLocation _location; + private final UnresolvedForwardReference _reference; private final Class<?> _beanType; - public Referring(JsonLocation location, Class<?> beanType) - { - _location = location; + public Referring(UnresolvedForwardReference ref, Class<?> beanType) { + _reference = ref; _beanType = beanType; } - public JsonLocation getLocation() { return _location; } + public JsonLocation getLocation() { return _reference.getLocation(); } public Class<?> getBeanType() { return _beanType; } - public abstract void handleResolvedForwardReference(Object id, Object value) - throws IOException; + public abstract void handleResolvedForwardReference(Object id, Object value) throws IOException; + public final boolean hasId(Object id) { + return id.equals(_reference.getUnresolvedId()); + } } } diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/CollectionDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/CollectionDeserializer.java index 8a8b1d4c7..e8c05f2fa 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/CollectionDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/CollectionDeserializer.java @@ -329,7 +329,7 @@ public class CollectionDeserializer Collection<Object> previous = _result; while (iterator.hasNext()) { UnresolvedId unresolvedId = iterator.next(); - if (unresolvedId._id.equals(id)) { + if (unresolvedId.hasId(id)) { iterator.remove(); previous.add(value); previous.addAll(unresolvedId._next); @@ -350,17 +350,15 @@ public class CollectionDeserializer */ private final static class UnresolvedId extends Referring { private final CollectionReferringAccumulator _parent; - private final Object _id; private final List<Object> _next = new ArrayList<Object>(); - private UnresolvedId(CollectionReferringAccumulator parent, UnresolvedForwardReference reference, - Class<?> contentType) + private UnresolvedId(CollectionReferringAccumulator parent, + UnresolvedForwardReference reference, Class<?> contentType) { - super(reference.getLocation(), contentType); + super(reference, contentType); _parent = parent; - _id = reference.getUnresolvedId(); } - + @Override public void handleResolvedForwardReference(Object id, Object value) throws IOException { _parent.resolveForwardReference(id, value); diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/MapDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/MapDeserializer.java index 0e0b70071..6b937d1e1 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/MapDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/MapDeserializer.java @@ -374,7 +374,7 @@ public class MapDeserializer MapReferringAccumulator referringAccumulator = null; boolean useObjectId = valueDes.getObjectIdReader() != null; if (useObjectId) { - referringAccumulator = new MapReferringAccumulator(result); + referringAccumulator = new MapReferringAccumulator(_mapType.getContentType().getRawClass(), result); } for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { // Must point to field name @@ -429,7 +429,7 @@ public class MapDeserializer MapReferringAccumulator referringAccumulator = null; boolean useObjectId = valueDes.getObjectIdReader() != null; if (useObjectId) { - referringAccumulator = new MapReferringAccumulator(result); + referringAccumulator = new MapReferringAccumulator(_mapType.getContentType().getRawClass(), result); } for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { // Must point to field name @@ -554,14 +554,16 @@ public class MapDeserializer reference.getRoid().appendReferring(referring); } - private final class MapReferringAccumulator { + private final static class MapReferringAccumulator { + private final Class<?> _valueType; private Map<Object,Object> _result; /** * A list of {@link UnresolvedId} to maintain ordering. */ private List<UnresolvedId> _accumulator = new ArrayList<UnresolvedId>(); - public MapReferringAccumulator(Map<Object, Object> result) { + public MapReferringAccumulator(Class<?> valueType, Map<Object, Object> result) { + _valueType = valueType; _result = result; } @@ -577,14 +579,12 @@ public class MapDeserializer public Referring handleUnresolvedReference(UnresolvedForwardReference reference, Object key) { - UnresolvedId id = new UnresolvedId(key, reference.getUnresolvedId(), reference.getLocation(), - _mapType.getContentType().getRawClass()); + UnresolvedId id = new UnresolvedId(this, reference, _valueType, key); _accumulator.add(id); return id; } - public void resolveForwardReference(Object id, Object value) - throws IOException + public void resolveForwardReference(Object id, Object value) throws IOException { Iterator<UnresolvedId> iterator = _accumulator.iterator(); // Resolve ordering after resolution of an id. This mean either: @@ -593,7 +593,7 @@ public class MapDeserializer Map<Object,Object> previous = _result; while (iterator.hasNext()) { UnresolvedId unresolvedId = iterator.next(); - if (unresolvedId._id.equals(id)) { + if (unresolvedId.hasId(id)) { iterator.remove(); previous.put(unresolvedId._key, value); previous.putAll(unresolvedId._next); @@ -605,30 +605,30 @@ public class MapDeserializer throw new IllegalArgumentException("Trying to resolve a forward reference with id [" + id + "] that wasn't previously seen as unresolved."); } + } - /** - * Helper class to maintain processing order of value. The resolved - * object associated with {@link #_id} comes before the values in - * {@link _next}. - */ - private final class UnresolvedId extends Referring { - private final Object _id; - private final Map<Object, Object> _next = new LinkedHashMap<Object, Object>(); - private final Object _key; - - private UnresolvedId(Object key, Object id, JsonLocation location, - Class<?> valueType) - { - super(location, valueType); - _key = key; - _id = id; - } + /** + * Helper class to maintain processing order of value. The resolved + * object associated with {@link #_id} comes before the values in + * {@link _next}. + */ + private final static class UnresolvedId extends Referring { + private final MapReferringAccumulator _parent; + private final Map<Object, Object> _next = new LinkedHashMap<Object, Object>(); + private final Object _key; + + private UnresolvedId(MapReferringAccumulator parent, UnresolvedForwardReference ref, + Class<?> valueType, Object key) + { + super(ref, valueType); + _parent = parent; + _key = key; + } - @Override - public void handleResolvedForwardReference(Object id, Object value) throws IOException - { - resolveForwardReference(id, value); - } + @Override + public void handleResolvedForwardReference(Object id, Object value) throws IOException + { + _parent.resolveForwardReference(id, value); } } } |