| package com.fasterxml.jackson.databind.node; |
| |
| import java.io.IOException; |
| |
| import com.fasterxml.jackson.core.*; |
| import com.fasterxml.jackson.core.io.CharTypes; |
| import com.fasterxml.jackson.core.io.NumberInput; |
| import com.fasterxml.jackson.core.util.ByteArrayBuilder; |
| |
| import com.fasterxml.jackson.databind.SerializerProvider; |
| import com.fasterxml.jackson.databind.exc.InvalidFormatException; |
| |
| /** |
| * Value node that contains a text value. |
| */ |
| public class TextNode |
| extends ValueNode |
| { |
| final static TextNode EMPTY_STRING_NODE = new TextNode(""); |
| |
| protected final String _value; |
| |
| public TextNode(String v) { _value = v; } |
| |
| /** |
| * Factory method that should be used to construct instances. |
| * For some common cases, can reuse canonical instances: currently |
| * this is the case for empty Strings, in future possible for |
| * others as well. If null is passed, will return null. |
| * |
| * @return Resulting {@link TextNode} object, if <b>v</b> |
| * is NOT null; null if it is. |
| */ |
| public static TextNode valueOf(String v) |
| { |
| if (v == null) { |
| return null; |
| } |
| if (v.length() == 0) { |
| return EMPTY_STRING_NODE; |
| } |
| return new TextNode(v); |
| } |
| |
| @Override |
| public JsonNodeType getNodeType() { |
| return JsonNodeType.STRING; |
| } |
| |
| @Override public JsonToken asToken() { return JsonToken.VALUE_STRING; } |
| |
| @Override |
| public String textValue() { |
| return _value; |
| } |
| |
| /** |
| * Method for accessing textual contents assuming they were |
| * base64 encoded; if so, they are decoded and resulting binary |
| * data is returned. |
| */ |
| @SuppressWarnings("resource") |
| public byte[] getBinaryValue(Base64Variant b64variant) throws IOException |
| { |
| final String str = _value.trim(); |
| ByteArrayBuilder builder = new ByteArrayBuilder(4 + ((str.length() * 3) << 2)); |
| try { |
| b64variant.decode(str, builder); |
| } catch (IllegalArgumentException e) { |
| throw InvalidFormatException.from(null, |
| String.format( |
| "Cannot access contents of TextNode as binary due to broken Base64 encoding: %s", |
| e.getMessage()), |
| str, byte[].class); |
| } |
| return builder.toByteArray(); |
| } |
| |
| @Override |
| public byte[] binaryValue() throws IOException { |
| return getBinaryValue(Base64Variants.getDefaultVariant()); |
| } |
| |
| /* |
| /********************************************************** |
| /* General type coercions |
| /********************************************************** |
| */ |
| |
| @Override |
| public String asText() { |
| return _value; |
| } |
| |
| @Override |
| public String asText(String defaultValue) { |
| return (_value == null) ? defaultValue : _value; |
| } |
| |
| // note: neither fast nor elegant, but these work for now: |
| |
| @Override |
| public boolean asBoolean(boolean defaultValue) { |
| if (_value != null) { |
| String v = _value.trim(); |
| if ("true".equals(v)) { |
| return true; |
| } |
| if ("false".equals(v)) { |
| return false; |
| } |
| } |
| return defaultValue; |
| } |
| |
| @Override |
| public int asInt(int defaultValue) { |
| return NumberInput.parseAsInt(_value, defaultValue); |
| } |
| |
| @Override |
| public long asLong(long defaultValue) { |
| return NumberInput.parseAsLong(_value, defaultValue); |
| } |
| |
| @Override |
| public double asDouble(double defaultValue) { |
| return NumberInput.parseAsDouble(_value, defaultValue); |
| } |
| |
| /* |
| /********************************************************** |
| /* Serialization |
| /********************************************************** |
| */ |
| |
| @Override |
| public final void serialize(JsonGenerator g, SerializerProvider provider) throws IOException |
| { |
| if (_value == null) { |
| g.writeNull(); |
| } else { |
| g.writeString(_value); |
| } |
| } |
| |
| /* |
| /********************************************************** |
| /* Overridden standard methods |
| /********************************************************** |
| */ |
| |
| @Override |
| public boolean equals(Object o) |
| { |
| if (o == this) return true; |
| if (o == null) return false; |
| if (o instanceof TextNode) { |
| return ((TextNode) o)._value.equals(_value); |
| } |
| return false; |
| } |
| |
| @Override |
| public int hashCode() { return _value.hashCode(); } |
| |
| /** |
| * Different from other values, Strings need quoting |
| */ |
| @Override |
| public String toString() |
| { |
| int len = _value.length(); |
| len = len + 2 + (len >> 4); |
| StringBuilder sb = new StringBuilder(len); |
| appendQuoted(sb, _value); |
| return sb.toString(); |
| } |
| |
| protected static void appendQuoted(StringBuilder sb, String content) |
| { |
| sb.append('"'); |
| CharTypes.appendQuoted(sb, content); |
| sb.append('"'); |
| } |
| } |