1 package com.fasterxml.jackson.databind.node; 2 3 import java.io.IOException; 4 5 import com.fasterxml.jackson.core.*; 6 import com.fasterxml.jackson.core.io.CharTypes; 7 import com.fasterxml.jackson.core.io.NumberInput; 8 import com.fasterxml.jackson.core.util.ByteArrayBuilder; 9 10 import com.fasterxml.jackson.databind.SerializerProvider; 11 import com.fasterxml.jackson.databind.exc.InvalidFormatException; 12 13 /** 14 * Value node that contains a text value. 15 */ 16 public class TextNode 17 extends ValueNode 18 { 19 private static final long serialVersionUID = 2L; 20 21 final static TextNode EMPTY_STRING_NODE = new TextNode(""); 22 23 protected final String _value; 24 TextNode(String v)25 public TextNode(String v) { _value = v; } 26 27 /** 28 * Factory method that should be used to construct instances. 29 * For some common cases, can reuse canonical instances: currently 30 * this is the case for empty Strings, in future possible for 31 * others as well. If null is passed, will return null. 32 * 33 * @return Resulting {@link TextNode} object, if <b>v</b> 34 * is NOT null; null if it is. 35 */ valueOf(String v)36 public static TextNode valueOf(String v) 37 { 38 if (v == null) { 39 return null; 40 } 41 if (v.length() == 0) { 42 return EMPTY_STRING_NODE; 43 } 44 return new TextNode(v); 45 } 46 47 @Override getNodeType()48 public JsonNodeType getNodeType() { 49 return JsonNodeType.STRING; 50 } 51 asToken()52 @Override public JsonToken asToken() { return JsonToken.VALUE_STRING; } 53 54 @Override textValue()55 public String textValue() { 56 return _value; 57 } 58 59 /** 60 * Method for accessing textual contents assuming they were 61 * base64 encoded; if so, they are decoded and resulting binary 62 * data is returned. 63 */ 64 @SuppressWarnings("resource") getBinaryValue(Base64Variant b64variant)65 public byte[] getBinaryValue(Base64Variant b64variant) throws IOException 66 { 67 final String str = _value.trim(); 68 ByteArrayBuilder builder = new ByteArrayBuilder(4 + ((str.length() * 3) >> 2)); 69 try { 70 b64variant.decode(str, builder); 71 } catch (IllegalArgumentException e) { 72 throw InvalidFormatException.from(null, 73 String.format( 74 "Cannot access contents of TextNode as binary due to broken Base64 encoding: %s", 75 e.getMessage()), 76 str, byte[].class); 77 } 78 return builder.toByteArray(); 79 } 80 81 @Override binaryValue()82 public byte[] binaryValue() throws IOException { 83 return getBinaryValue(Base64Variants.getDefaultVariant()); 84 } 85 86 /* 87 /********************************************************** 88 /* General type coercions 89 /********************************************************** 90 */ 91 92 @Override asText()93 public String asText() { 94 return _value; 95 } 96 97 @Override asText(String defaultValue)98 public String asText(String defaultValue) { 99 return (_value == null) ? defaultValue : _value; 100 } 101 102 // note: neither fast nor elegant, but these work for now: 103 104 @Override asBoolean(boolean defaultValue)105 public boolean asBoolean(boolean defaultValue) { 106 if (_value != null) { 107 String v = _value.trim(); 108 if ("true".equals(v)) { 109 return true; 110 } 111 if ("false".equals(v)) { 112 return false; 113 } 114 } 115 return defaultValue; 116 } 117 118 @Override asInt(int defaultValue)119 public int asInt(int defaultValue) { 120 return NumberInput.parseAsInt(_value, defaultValue); 121 } 122 123 @Override asLong(long defaultValue)124 public long asLong(long defaultValue) { 125 return NumberInput.parseAsLong(_value, defaultValue); 126 } 127 128 @Override asDouble(double defaultValue)129 public double asDouble(double defaultValue) { 130 return NumberInput.parseAsDouble(_value, defaultValue); 131 } 132 133 /* 134 /********************************************************** 135 /* Serialization 136 /********************************************************** 137 */ 138 139 @Override serialize(JsonGenerator g, SerializerProvider provider)140 public final void serialize(JsonGenerator g, SerializerProvider provider) throws IOException 141 { 142 if (_value == null) { 143 g.writeNull(); 144 } else { 145 g.writeString(_value); 146 } 147 } 148 149 /* 150 /********************************************************** 151 /* Overridden standard methods 152 /********************************************************** 153 */ 154 155 @Override equals(Object o)156 public boolean equals(Object o) 157 { 158 if (o == this) return true; 159 if (o == null) return false; 160 if (o instanceof TextNode) { 161 return ((TextNode) o)._value.equals(_value); 162 } 163 return false; 164 } 165 166 @Override hashCode()167 public int hashCode() { return _value.hashCode(); } 168 169 @Deprecated // since 2.10 appendQuoted(StringBuilder sb, String content)170 protected static void appendQuoted(StringBuilder sb, String content) 171 { 172 sb.append('"'); 173 CharTypes.appendQuoted(sb, content); 174 sb.append('"'); 175 } 176 } 177