• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.util;
2 
3 import com.fasterxml.jackson.core.*;
4 import com.fasterxml.jackson.core.json.JsonReadContext;
5 
6 /**
7  * Implementation of {@link JsonStreamContext} used by {@link TokenBuffer}
8  * to link back to the original context to try to keep location information
9  * consistent between source location and buffered content when it's re-read
10  * from the buffer.
11  *
12  * @since 2.9
13  */
14 public class TokenBufferReadContext extends JsonStreamContext
15 {
16     protected final JsonStreamContext _parent;
17 
18     protected final JsonLocation _startLocation;
19 
20     // Benefit for reusing?
21 //    protected JsonReadContext _child;
22 
23     /*
24     /**********************************************************
25     /* Location/state information (minus source reference)
26     /**********************************************************
27      */
28 
29     protected String _currentName;
30 
31     protected Object _currentValue;
32 
TokenBufferReadContext(JsonStreamContext base, Object srcRef)33     protected TokenBufferReadContext(JsonStreamContext base, Object srcRef) {
34         super(base);
35         _parent = base.getParent();
36         _currentName = base.getCurrentName();
37         _currentValue = base.getCurrentValue();
38         if (base instanceof JsonReadContext) {
39             JsonReadContext rc = (JsonReadContext) base;
40             _startLocation = rc.getStartLocation(srcRef);
41         } else {
42             _startLocation = JsonLocation.NA;
43         }
44     }
45 
TokenBufferReadContext(JsonStreamContext base, JsonLocation startLoc)46     protected TokenBufferReadContext(JsonStreamContext base, JsonLocation startLoc) {
47         super(base);
48         _parent = base.getParent();
49         _currentName = base.getCurrentName();
50         _currentValue = base.getCurrentValue();
51         _startLocation = startLoc;
52     }
53 
54     /**
55      * Constructor for case where there is no real surrounding context: just create
56      * virtual ROOT
57      */
TokenBufferReadContext()58     protected TokenBufferReadContext() {
59         super(TYPE_ROOT, -1);
60         _parent = null;
61         _startLocation = JsonLocation.NA;
62     }
63 
TokenBufferReadContext(TokenBufferReadContext parent, int type, int index)64     protected TokenBufferReadContext(TokenBufferReadContext parent, int type, int index) {
65         super(type, index);
66         _parent = parent;
67         _startLocation = parent._startLocation;
68     }
69 
70     @Override
getCurrentValue()71     public Object getCurrentValue() {
72         return _currentValue;
73     }
74 
75     @Override
setCurrentValue(Object v)76     public void setCurrentValue(Object v) {
77         _currentValue = v;
78     }
79 
80     /*
81     /**********************************************************
82     /* Factory methods
83     /**********************************************************
84      */
85 
createRootContext(JsonStreamContext origContext)86     public static TokenBufferReadContext createRootContext(JsonStreamContext origContext) {
87         // First: possible to have no current context; if so, just create bogus ROOT context
88         if (origContext == null) {
89             return new TokenBufferReadContext();
90         }
91         return new TokenBufferReadContext(origContext, null);
92     }
93 
createChildArrayContext()94     public TokenBufferReadContext createChildArrayContext() {
95         // For current context there will be one next Array value, first:
96         ++_index;
97         return new TokenBufferReadContext(this, TYPE_ARRAY, -1);
98     }
99 
createChildObjectContext()100     public TokenBufferReadContext createChildObjectContext() {
101         // For current context there will be one next Object value, first:
102         ++_index;
103         return new TokenBufferReadContext(this, TYPE_OBJECT, -1);
104     }
105 
106     /**
107      * Helper method we need to handle discontinuity between "real" contexts buffer
108      * creates, and ones from parent: problem being they are of different types.
109      */
parentOrCopy()110     public TokenBufferReadContext parentOrCopy() {
111         // 30-Apr-2017, tatu: This is bit awkward since part on ancestor stack is of different
112         //     type (usually `JsonReadContext`)... and so for unbalanced buffers (with extra
113         //     END_OBJECT / END_ARRAY), we may need to create
114         if (_parent instanceof TokenBufferReadContext) {
115             return (TokenBufferReadContext) _parent;
116         }
117         if (_parent == null) { // unlikely, but just in case let's support
118             return new TokenBufferReadContext();
119         }
120         return new TokenBufferReadContext(_parent, _startLocation);
121     }
122 
123     /*
124     /**********************************************************
125     /* Abstract method implementation
126     /**********************************************************
127      */
128 
getCurrentName()129     @Override public String getCurrentName() { return _currentName; }
130 
131     // @since 2.9
hasCurrentName()132     @Override public boolean hasCurrentName() { return _currentName != null; }
133 
getParent()134     @Override public JsonStreamContext getParent() { return _parent; }
135 
setCurrentName(String name)136     public void setCurrentName(String name) throws JsonProcessingException {
137         _currentName = name;
138     }
139 
140     /*
141     /**********************************************************
142     /* Extended support for context updates
143     /**********************************************************
144      */
145 
146     /**
147      * @since 2.10.1
148      */
updateForValue()149     public void updateForValue() {
150         ++_index;
151     }
152 }
153