public class NullSafeType<T> extends FieldType<T>
FieldType
that wraps any other FieldType
not supporting null values and adds support for null values.
This class pre-pends a 0x01
to the binary encoding of non-null values, and uses a single 0xff
byte to
represent null values. Therefore, null values sort last.
The default value becomes null, for which "null"
is the value returned by toParseableString()
.
Therefore, "null"
must not be returned by the wrapped type's toParseableString()
for any value.
This class will automatically "inline" the 0xff
for null values and omit the 0x01
for non-null values
if the wrapped FieldType
's FieldType.hasPrefix0xff()
method returns false.
Modifier and Type | Field and Description |
---|---|
protected FieldType<T> |
inner
The inner
FieldType that this instance wraps. |
static int |
NOT_NULL_SENTINEL
Not null sentinel byte value.
|
static int |
NULL_SENTINEL
Null sentinel byte value.
|
name, NAME_PATTERN, REFERENCE_TYPE_NAME, signature, typeToken
Constructor and Description |
---|
NullSafeType(FieldType<T> inner)
Constructor.
|
NullSafeType(String name,
FieldType<T> inner)
Constructor.
|
Modifier and Type | Method and Description |
---|---|
int |
compare(T value1,
T value2)
Order two field values.
|
<S> T |
convert(FieldType<S> type,
S value)
|
boolean |
equals(Object obj) |
T |
fromParseableString(ParseContext context)
Parse a value previously encoded by
toParseableString() as a self-delimited String
and positioned at the start of the given parsing context. |
T |
fromString(String string)
Parse a non-null value previously encoded by
toString(T) . |
NullSafeType<T> |
genericizeForIndex()
Remove any information that may differ between instances associated with the same indexed field in the same schema.
|
int |
hashCode() |
boolean |
hasPrefix0x00()
Determine whether any of this field type's encoded values start with a
0x00 byte. |
boolean |
hasPrefix0xff()
Determine whether any of this field type's encoded values start with a
0xff byte. |
T |
read(ByteReader reader)
Read a value from the given input.
|
void |
skip(ByteReader reader)
Read and discard a value from the given input.
|
String |
toParseableString(T value)
Encode a possibly null value as a
String for later decoding by fromParseableString() . |
String |
toString(T value)
Encode a non-null value as a
String for later decoding by fromString() . |
void |
write(ByteWriter writer,
T value)
Write a value to the given output.
|
getDefaultValue, getDefaultValueObject, getEncodingSignature, getKeyRange, getName, getTypeToken, toString, validate, validateAndWrite
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
comparing, comparing, comparingDouble, comparingInt, comparingLong, naturalOrder, nullsFirst, nullsLast, reversed, reverseOrder, thenComparing, thenComparing, thenComparing, thenComparingDouble, thenComparingInt, thenComparingLong
public static final int NOT_NULL_SENTINEL
public static final int NULL_SENTINEL
public NullSafeType(String name, FieldType<T> inner)
name
- type nameinner
- inner type that is not null safepublic NullSafeType(FieldType<T> inner)
inner
; therefore, this instance and inner
cannot be both registered in a FieldTypeRegistry
.inner
- inner type that is not null safepublic T read(ByteReader reader)
FieldType
public void write(ByteWriter writer, T value)
FieldType
public void skip(ByteReader reader)
FieldType
public T fromString(String string)
FieldType
toString(T)
.
The implementation in FieldType
creates a new ParseContext
based on string
,
delegates to FieldType.toParseableString(T)
to parse it, and verifies that all of string
was consumed
during the parse. Subclasses that override this method should also override toString(T)
.
fromString
in class FieldType<T>
string
- non-null value previously encoded as a String
by toString(T)
public String toString(T value)
FieldType
String
for later decoding by fromString()
.
Each of the characters in the returned String
must be one of the valid XML characters
(tab, newline, carriage return, \u0020 - \ud7ff
, and \ue000 - \fffdf
).
The implementation in FieldType
checks that value
is not null, then delegates to FieldType.toParseableString(T)
.
Subclasses that override this method should also override fromString()
.
toString
in class FieldType<T>
value
- actual value, never nullvalue
acceptable to fromString()
public T fromParseableString(ParseContext context)
FieldType
toParseableString()
as a self-delimited String
and positioned at the start of the given parsing context.fromParseableString
in class FieldType<T>
context
- parse context starting with a string previously encoded via toParseableString()
public String toParseableString(T value)
FieldType
String
for later decoding by fromParseableString()
.
The string value must be self-delimiting, i.e., decodable even when followed by arbitrary additional characters,
and must not start with whitespace or closing square bracket ("]"
).
In addition, each of the characters in the returned String
must be one of the valid XML characters
(tab, newline, carriage return, \u0020 - \ud7ff
, and \ue000 - \fffdf
).
toParseableString
in class FieldType<T>
value
- actual value (possibly null)value
acceptable to fromParseableString()
public <S> T convert(FieldType<S> type, S value)
FieldType
FieldType
into a value of this FieldType
.
For a non-null value
, the implementation in FieldType
first checks whether the value
is already
a valid value for this type; if so, the value is returned. Otherwise, it invokes type.
toString(value)
to convert value
into a String
, and then attempts to parse that string via
this.
fromString()
; if the parse fails, an IllegalArgumentException
is thrown.
If value
is null, the implementation in FieldType
returns null, unless this type does not support null
values, in which case an IllegalArgumentException
is thrown.
Special handling also exists for certain conversions between built-in types:
value != 0
char
and a String
of length one are convertible (other String
s are not)char[]
array and a String
are convertiblepublic int compare(T value1, T value2)
FieldType
This method must provide a total ordering of all supported Java values that is consistent with the database ordering,
i.e., the unsigned lexicographical ordering of the corresponding byte[]
encoded field values.
If null is a supported Java value, then the returned Comparator
must accept null parameters without
throwing an exception (note, this is a stronger requirement than the Comparator
interface normally requires).
Note: by convention, null values usually sort last.
public boolean hasPrefix0xff()
FieldType
0xff
byte.
Certain optimizations are possible when this is not the case. It is safe for this method to always return true.
Note: changing the return value of this method usually means changing the binary encoding, resulting in an incompatible type.
The implementation in FieldType
returns true
.
hasPrefix0xff
in class FieldType<T>
0xff
existspublic boolean hasPrefix0x00()
FieldType
0x00
byte.
Certain optimizations are possible when this is not the case. It is safe for this method to always return true.
Note: changing the return value of this method usually means changing the binary encoding, resulting in an incompatible type.
The implementation in FieldType
returns true
.
hasPrefix0x00
in class FieldType<T>
0x00
existspublic NullSafeType<T> genericizeForIndex()
FieldType
This operation should be applied before using this instance with index queries.
genericizeForIndex
in class FieldType<T>
Copyright © 2019. All rights reserved.