1 package com.fasterxml.jackson.databind.node;
2
3 import java.math.BigDecimal;
4 import java.math.BigInteger;
5
6 import com.fasterxml.jackson.databind.JsonNode;
7 import com.fasterxml.jackson.databind.util.RawValue;
8
9 /**
10 * Base class that specifies methods for getting access to
11 * Node instances (newly constructed, or shared, depending
12 * on type), as well as basic implementation of the methods.
13 * Designed to be sub-classed if extended functionality (additions
14 * to behavior of node types, mostly) is needed.
15 */
16 public class JsonNodeFactory
17 implements java.io.Serializable, // since 2.1
18 JsonNodeCreator // since 2.3
19 {
20 // with 2.2
21 private static final long serialVersionUID = 1L;
22
23 private final boolean _cfgBigDecimalExact;
24
25 private static final JsonNodeFactory decimalsNormalized
26 = new JsonNodeFactory(false);
27 private static final JsonNodeFactory decimalsAsIs
28 = new JsonNodeFactory(true);
29
30 /**
31 * Default singleton instance that construct "standard" node instances:
32 * given that this class is stateless, a globally shared singleton
33 * can be used.
34 */
35 public final static JsonNodeFactory instance = decimalsNormalized;
36
37 /**
38 * Main constructor
39 *
40 * <p>The only argument to this constructor is a boolean telling whether
41 * {@link DecimalNode} instances must be built with exact representations of
42 * {@link BigDecimal} instances.</p>
43 *
44 * <p>This has quite an influence since, for instance, a BigDecimal (and,
45 * therefore, a DecimalNode) constructed from input string {@code "1.0"} and
46 * another constructed with input string {@code "1.00"} <b>will not</b> be
47 * equal, since their scale differs (1 in the first case, 2 in the second
48 * case).</p>
49 *
50 * <p>Note that setting the argument to {@code true} does <i>not</i>
51 * guarantee a strict inequality between JSON representations: input texts
52 * {@code "0.1"} and {@code "1e-1"}, for instance, yield two equivalent
53 * BigDecimal instances since they have the same scale (1).</p>
54 *
55 * <p>The no-arg constructor (and the default {@link #instance}) calls this
56 * constructor with {@code false} as an argument.</p>
57 *
58 * @param bigDecimalExact see description
59 *
60 * @see BigDecimal
61 */
62 public JsonNodeFactory(boolean bigDecimalExact)
63 {
64 _cfgBigDecimalExact = bigDecimalExact;
65 }
66
67 /**
68 * Default constructor
69 *
70 * <p>This calls {@link #JsonNodeFactory(boolean)} with {@code false}
71 * as an argument.</p>
72 */
73 protected JsonNodeFactory()
74 {
75 this(false);
76 }
77
78 /**
79 * Return a factory instance with the desired behavior for BigDecimals
80 * <p>See {@link #JsonNodeFactory(boolean)} for a full description.</p>
81 *
82 * @param bigDecimalExact see description
83 * @return a factory instance
84 */
85 public static JsonNodeFactory withExactBigDecimals(boolean bigDecimalExact)
86 {
87 return bigDecimalExact ? decimalsAsIs : decimalsNormalized;
88 }
89
90 /*
91 /**********************************************************
92 /* Factory methods for literal values
93 /**********************************************************
94 */
95
96 /**
97 * Factory method for getting an instance of JSON boolean value
98 * (either literal 'true' or 'false')
99 */
100 @Override
101 public BooleanNode booleanNode(boolean v) {
102 return v ? BooleanNode.getTrue() : BooleanNode.getFalse();
103 }
104
105 /**
106 * Factory method for getting an instance of JSON null node (which
107 * represents literal null value)
108 */
109 @Override
110 public NullNode nullNode() { return NullNode.getInstance(); }
111
112 public JsonNode missingNode() {
113 return MissingNode.getInstance();
114 }
115
116 /*
117 /**********************************************************
118 /* Factory methods for numeric values
119 /**********************************************************
120 */
121
122 /**
123 * Factory method for getting an instance of JSON numeric value
124 * that expresses given 8-bit value
125 */
126 @Override
127 public NumericNode numberNode(byte v) { return IntNode.valueOf(v); }
128
129 /**
130 * Alternate factory method that will handle wrapper value, which may
131 * be null.
132 * Due to possibility of null, returning type is not guaranteed to be
133 * {@link NumericNode}, but just {@link ValueNode}.
134 */
135 @Override
136 public ValueNode numberNode(Byte value) {
137 return (value == null) ? nullNode() : IntNode.valueOf(value.intValue());
138 }
139
140 /**
141 * Factory method for getting an instance of JSON numeric value
142 * that expresses given 16-bit integer value
143 */
144 @Override
145 public NumericNode numberNode(short v) { return ShortNode.valueOf(v); }
146
147 /**
148 * Alternate factory method that will handle wrapper value, which may
149 * be null.
150 * Due to possibility of null, returning type is not guaranteed to be
151 * {@link NumericNode}, but just {@link ValueNode}.
152 */
153 @Override
154 public ValueNode numberNode(Short value) {
155 return (value == null) ? nullNode() : ShortNode.valueOf(value);
156 }
157
158 /**
159 * Factory method for getting an instance of JSON numeric value
160 * that expresses given 32-bit integer value
161 */
162 @Override
163 public NumericNode numberNode(int v) { return IntNode.valueOf(v); }
164
165 /**
166 * Alternate factory method that will handle wrapper value, which may
167 * be null.
168 * Due to possibility of null, returning type is not guaranteed to be
169 * {@link NumericNode}, but just {@link ValueNode}.
170 */
171 @Override
172 public ValueNode numberNode(Integer value) {
173 return (value == null) ? nullNode() : IntNode.valueOf(value.intValue());
174 }
175
176 /**
177 * Factory method for getting an instance of JSON numeric value
178 * that expresses given 64-bit integer value
179 */
180 @Override
181 public NumericNode numberNode(long v) {
182 return LongNode.valueOf(v);
183 }
184
185 /**
186 * Alternate factory method that will handle wrapper value, which may be null.
187 * Due to possibility of null, returning type is not guaranteed to be
188 * {@link NumericNode}, but just {@link ValueNode}.
189 */
190 @Override
191 public ValueNode numberNode(Long v) {
192 if (v == null) {
193 return nullNode();
194 }
195 return LongNode.valueOf(v.longValue());
196 }
197
198 /**
199 * Factory method for getting an instance of JSON numeric value
200 * that expresses given unlimited range integer value
201 */
202 @Override
203 public ValueNode numberNode(BigInteger v) {
204 if (v == null) {
205 return nullNode();
206 }
207 return BigIntegerNode.valueOf(v);
208 }
209
210 /**
211 * Factory method for getting an instance of JSON numeric value
212 * that expresses given 32-bit floating point value
213 */
214 @Override
215 public NumericNode numberNode(float v) { return FloatNode.valueOf((float) v); }
216
217 /**
218 * Alternate factory method that will handle wrapper value, which may
219 * be null.
220 * Due to possibility of null, returning type is not guaranteed to be
221 * {@link NumericNode}, but just {@link ValueNode}.
222 */
223 @Override
224 public ValueNode numberNode(Float value) {
225 return (value == null) ? nullNode() : FloatNode.valueOf(value.floatValue());
226 }
227
228 /**
229 * Factory method for getting an instance of JSON numeric value
230 * that expresses given 64-bit floating point value
231 */
232 @Override
233 public NumericNode numberNode(double v) { return DoubleNode.valueOf(v); }
234
235 /**
236 * Alternate factory method that will handle wrapper value, which may
237 * be null.
238 * Due to possibility of null, returning type is not guaranteed to be
239 * {@link NumericNode}, but just {@link ValueNode}.
240 */
241 @Override
242 public ValueNode numberNode(Double value) {
243 return (value == null) ? nullNode() : DoubleNode.valueOf(value.doubleValue());
244 }
245
246 /**
247 * Factory method for getting an instance of JSON numeric value
248 * that expresses given unlimited precision floating point value
249 *
250 * <p>In the event that the factory has been built to normalize decimal
251 * values, the BigDecimal argument will be stripped off its trailing zeroes,
252 * using {@link BigDecimal#stripTrailingZeros()}.</p>
253 *
254 * @see #JsonNodeFactory(boolean)
255 */
256 @Override
257 public ValueNode numberNode(BigDecimal v)
258 {
259 if (v == null) {
260 return nullNode();
261 }
262
263 /*
264 * If the user wants the exact representation of this big decimal,
265 * return the value directly
266 */
267 if (_cfgBigDecimalExact)
268 return DecimalNode.valueOf(v);
269
270 /*
271 * If the user has asked to strip trailing zeroes, however, there is
272 * this bug to account for:
273 *
274 * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6480539
275 *
276 * In short: zeroes are never stripped out of 0! We therefore _have_
277 * to compare with BigDecimal.ZERO...
278 */
279 return v.compareTo(BigDecimal.ZERO) == 0 ? DecimalNode.ZERO
280 : DecimalNode.valueOf(v.stripTrailingZeros());
281 }
282
283 /*
284 /**********************************************************
285 /* Factory methods for textual values
286 /**********************************************************
287 */
288
289 /**
290 * Factory method for constructing a node that represents JSON
291 * String value
292 */
293 @Override
294 public TextNode textNode(String text) { return TextNode.valueOf(text); }
295
296 /**
297 * Factory method for constructing a node that represents given
298 * binary data, and will get serialized as equivalent base64-encoded
299 * String value
300 */
301 @Override
302 public BinaryNode binaryNode(byte[] data) { return BinaryNode.valueOf(data); }
303
304 /**
305 * Factory method for constructing a node that represents given
306 * binary data, and will get serialized as equivalent base64-encoded
307 * String value
308 */
309 @Override
310 public BinaryNode binaryNode(byte[] data, int offset, int length) {
311 return BinaryNode.valueOf(data, offset, length);
312 }
313
314 /*
315 /**********************************************************
316 /* Factory method for structured values
317 /**********************************************************
318 */
319
320 /**
321 * Factory method for constructing an empty JSON Array node
322 */
323 @Override
324 public ArrayNode arrayNode() { return new ArrayNode(this); }
325
326 /**
327 * Factory method for constructing a JSON Array node with an initial capacity
328 *
329 * @since 2.8
330 */
331 @Override
332 public ArrayNode arrayNode(int capacity) { return new ArrayNode(this, capacity); }
333
334 /**
335 * Factory method for constructing an empty JSON Object ("struct") node
336 */
337 @Override
338 public ObjectNode objectNode() { return new ObjectNode(this); }
339
340 /**
341 * Factory method for constructing a wrapper for POJO
342 * ("Plain Old Java Object") objects; these will get serialized
343 * using data binding, usually as JSON Objects, but in some
344 * cases as JSON Strings or other node types.
345 */
346 @Override
347 public ValueNode pojoNode(Object pojo) { return new POJONode(pojo); }
348
349 @Override
350 public ValueNode rawValueNode(RawValue value) {
351 return new POJONode(value);
352 }
353
354 /*
355 /**********************************************************
356 /* Helper methods
357 /**********************************************************
358 */
359
360 protected boolean _inIntRange(long l)
361 {
362 int i = (int) l;
363 long l2 = (long) i;
364 return (l2 == l);
365 }
366 }
367
368