All Downloads are FREE. Search and download functionalities are using the official Maven repository.

oracle.nosql.driver.values.FieldValueEventHandler Maven / Gradle / Ivy

There is a newer version: 5.4.16
Show newest version
/*-
 * 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