oracle.nosql.driver.values.FieldValueEventHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nosqldriver Show documentation
Show all versions of nosqldriver Show documentation
Java examples for Oracle NoSQL Database
/*-
* Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* https://oss.oracle.com/licenses/upl/
*/
package oracle.nosql.driver.values;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Map;
/**
* FieldValueEventHandler is an event-driven interface that allows multiple
* implementations of serializers and deserializers for a {@link FieldValue}.
* The events correspond to the data model exposed by {@link FieldValue}.
*
* Events can be generated from {@link FieldValue} instances themselves,
* from a wire protocol, or from a generic program. Examples of uses include
*
* - Binary serializer for the wire protocol, capturing events generated
* from a {@link FieldValue} instances
* - Binary de-serializer for the wire protocol, capturing events generated
* from code that is reading the wire protocol
* - JSON serializer for {@link FieldValue} instances
* - JSON pretty-printfor {@link FieldValue} instances
* - Direct-from/to-object serializer or deserializer that operates on
* POJOs intead of {@link FieldValue}
*
*
* In addition to the interface this file includes static methods to generate
* events from a {@link FieldValue} instance. See {@link #generate}.
*
* Example usage
*
* MapValue map = new MapValue();
* map.put(...);
* ...
* JsonSerializer js = new JsonSerializer(null);
* FieldValueEventHandler.generate(map, js);
* String json = js.toString();
*
*
* Functionally here is how the event handler is to be used. Look at the
* {@link #generate} method for implementation details. There are no
* specific start/end events, although they could be added if deemed useful.
*
* Simple (atomic) field value events are just that, e.g.
*
* booleanValue(true);
* integerValue(6);
*
* Map values have startMap and endMap events that surround
* them. These methods have a size argument to let the event handler know the
* size of the map. It's possible that the size is not known but it's best to
* provide one if possible, and in some cases (protocol serialization) it's
* required. Map entries require key and value, where the value may be a nested
* map or array. To account for nesting the events are:
*
* startMap(1)
* startMapField(key) // pass the key String
* // an event that creates a value, including a nested map or array
* stringValue("a string")
* endMapField()
* endMap(1)
*
* Array values have startArray and endArray events that
* surround them. These methods have a size argument to let the event handler
* know the size of the array. It's possible that the size is not known but
* it's best to provide one if possible, and in some cases (protocol
* serialization) it's required. Array entry events are followed with
* endArrayField events. This simplifies implementations that need to know if
* they are working within an array. Here's an array example.
*
* startArray(2)
* startMap(msize) // nested map
* endMap(msize) // map is empty
* endArrayField()
* stringValue("a string") // add string to the array
* endArrayField()
* endArray(2)
*
*/
public interface FieldValueEventHandler {
/**
* Start a MapValue. This method accepts the size of the map, but there
* are situations where the size may not be known. In this case -1
* should be passed and it is up to the implementing class to decide
* if it can operate without a size and if not, throw
* IllegalArgumentException.
*
* @param size the number of entries in the map or -1 if not known.
* @throws IllegalArgumentException if the size is invalid or cannot be
* handled by the implementation.
* @throws IOException conditionally, based on implementation
*/
void startMap(int size) throws IOException;
/**
* Start an ArrayValue. This method accepts the size of the array, but there
* are situations where the size may not be known. In this case -1
* should be passed and it is up to the implementing class to decide
* if it can operate without a size and if not, throw
* IllegalArgumentException.
*
* @param size the number of entries in the array or -1 if not known.
* @throws IllegalArgumentException if the size is invalid or cannot be
* handled by the implementation.
* @throws IOException conditionally, based on implementation
*/
void startArray(int size) throws IOException;
/**
* End a MapValue.
*
* @param size the number of entries in the map or -1 if not known.
* @throws IOException conditionally, based on implementation
*/
void endMap(int size) throws IOException;
/**
* End an ArrayValue.
*
* @param size the number of entries in the array or -1 if not known.
* @throws IOException conditionally, based on implementation
*/
void endArray(int size) throws IOException;
/**
* Start a field in a map.
*
* @param key the key of the field.
* @throws IOException conditionally, based on implementation
*/
void startMapField(String key) throws IOException;
/**
* End a field in a map.
* @throws IOException conditionally, based on implementation
*/
void endMapField() throws IOException;
/**
* End a field in an array. There is no corresponding start for
* array entries. This allows, for example, JSON serializers to insert
* array value separators without the complexity of tracking the
* entire event sequence.
* @throws IOException conditionally, based on implementation
*/
void endArrayField() throws IOException;
/**
* A boolean value
*
* @param value the value
* @throws IOException conditionally, based on implementation
*/
void booleanValue(boolean value) throws IOException;
/**
* A binary value
*
* @param byteArray the byte[] value
* @throws IOException conditionally, based on implementation
*/
void binaryValue(byte[] byteArray) throws IOException;
/**
* A String value
*
* @param value the value
* @throws IOException conditionally, based on implementation
*/
void stringValue(String value) throws IOException;
/**
* An integer value
*
* @param value the value
* @throws IOException conditionally, based on implementation
*/
void integerValue(int value) throws IOException;
/**
* A long value
*
* @param value the value
* @throws IOException conditionally, based on implementation
*/
void longValue(long value) throws IOException;
/**
* A double value
*
* @param value the value
* @throws IOException conditionally, based on implementation
*/
void doubleValue(double value) throws IOException;
/**
* A Number value.
*
* @param value the value
* @throws IOException conditionally, based on implementation
*/
void numberValue(BigDecimal value) throws IOException;
/**
* A Timestamp value
*
* @param timestamp the value
* @throws IOException conditionally, based on implementation
*/
void timestampValue(TimestampValue timestamp) throws IOException;
/**
* A JsonNullValue
* @throws IOException conditionally, based on implementation
*/
void jsonNullValue() throws IOException;
/**
* A NullValue
* @throws IOException conditionally, based on implementation
*/
void nullValue() throws IOException;
/**
* An EmptyValue
* @throws IOException conditionally, based on implementation
*/
void emptyValue() throws IOException;
/**
* Generates events from a {@link FieldValue} instance sending them to
* the {@link FieldValueEventHandler} provided.
*
* @param value the FieldValue used to generate events
* @param handler the handler to use
* @throws IOException conditionally, based on implementation
*/
public static void generate(FieldValue value,
FieldValueEventHandler handler)
throws IOException {
FieldValue.Type type = value.getType();
switch (type) {
case ARRAY:
generateForArray(value.asArray(), handler);
break;
case BINARY:
handler.binaryValue(value.getBinary());
break;
case BOOLEAN:
handler.booleanValue(value.getBoolean());
break;
case DOUBLE:
handler.doubleValue(value.getDouble());
break;
case INTEGER:
handler.integerValue(value.getInt());
break;
case LONG:
handler.longValue(value.getLong());
break;
case MAP:
generateForMap(value.asMap(), handler);
break;
case STRING:
handler.stringValue(value.asString().getString());
break;
case TIMESTAMP:
handler.timestampValue(value.asTimestamp());
break;
case NUMBER:
handler.numberValue(value.asNumber().getValue());
break;
case JSON_NULL:
handler.jsonNullValue();
break;
case NULL:
handler.nullValue();
break;
case EMPTY:
handler.emptyValue();
break;
default:
throw new IllegalStateException(
"FieldValueEventHandler, unknown type " + type);
}
}
/**
* Generates events for {@link MapValue} sending them to the specified
* {@link FieldValueEventHandler}.
*
* @param map the MapValue to use
* @param handler the handler to use
* @throws IOException conditionally, based on implementation
*/
public static void generateForMap(MapValue map,
FieldValueEventHandler handler)
throws IOException {
handler.startMap(map.size());
for (Map.Entry entry : map.entrySet()) {
handler.startMapField(entry.getKey());
generate(entry.getValue(), handler);
handler.endMapField();
}
handler.endMap(map.size());
}
/**
* Generates events for {@link ArrayValue} sending them to the specified
* {@link FieldValueEventHandler}.
*
* @param array the ArrayValue to use
* @param handler the handler to use
* @throws IOException conditionally, based on implementation
*/
public static void generateForArray(ArrayValue array,
FieldValueEventHandler handler)
throws IOException {
handler.startArray(array.size());
for (FieldValue value : array) {
generate(value, handler);
handler.endArrayField();
}
handler.endArray(array.size());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy