com.sleepycat.persist.impl.Accessor Maven / Gradle / Ivy
/*-
* Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This file was distributed by Oracle as part of a version of Oracle Berkeley
* DB Java Edition made available at:
*
* http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
*
* Please see the LICENSE file included in the top-level directory of the
* appropriate version of Oracle Berkeley DB Java Edition for a copy of the
* license and additional information.
*/
package com.sleepycat.persist.impl;
/**
* Field binding operations implemented via reflection (ReflectionAccessor) or
* bytecode enhancement (EnhancedAccessor).
*
* Normally we read the set of all secondary key fields first and then the
* set of all non-key fields, reading each set in order of field name. But
* when reading an old format record we must account for the following
* class evolution conversions:
*
* - Convert a field: pass value thru converter
* - Widen a field type: pass value thru widener
* - Add a field: don't read the new field
* - Delete a field: skip the deleted field
* - Rename a field: read field in a different order
*
* To support these operations, the methods for reading fields allow reading
* specific ranges of fields as well as all fields. For example, all fields
* up to a deleted field could be read, and then all fields from the following
* field onward.
*
* @author Mark Hayes
*/
interface Accessor {
/**
* A large field value to use instead of Integer.MAX_VALUE, to work around
* Java JIT compiler bug when doing an (X {@literal <=} Integer.MAX_VALUE)
* as would be done in readXxxKeyFields methods.
*/
final int MAX_FIELD_NUM = Integer.MAX_VALUE - 1;
/**
* Creates a new instance of the target class using its default
* constructor.
*/
Object newInstance();
/**
* Creates a new one dimensional array of the given length, having the
* target class as its component type.
*
* Using a special method for a one dimensional array, which can be
* implemented by bytecode generation, is a compromise. We use reflection
* to create multidimensional arrays. We could in the future generate code
* to create arrays as they are encountered, if there is a need to avoid
* reflection for multidimensional arrays.
*/
Object newArray(int len);
/**
* Returns whether the primary key field is null (for a reference type) or
* zero (for a primitive integer type). Null and zero are used as an
* indication that the key should be assigned from a sequence.
*/
boolean isPriKeyFieldNullOrZero(Object o);
/**
* Writes the primary key field value to the given EntityOutput.
*
* To write a primary key with a reference type, this method must call
* EntityOutput.writeKeyObject.
*
* @param o is the object whose primary key field is to be written.
*
* @param output the output data to write to.
*/
void writePriKeyField(Object o, EntityOutput output)
throws RefreshException;
/**
* Reads the primary key field value from the given EntityInput.
*
* To read a primary key with a reference type, this method must call
* EntityInput.readKeyObject.
*
* @param o is the object whose primary key field is to be read.
*
* @param input the input data to read from.
*/
void readPriKeyField(Object o, EntityInput input)
throws RefreshException;
/**
* Writes all secondary key field values to the given EntityOutput,
* writing fields in super classes first and in name order within class.
*
* @param o is the object whose secondary key fields are to be written.
*
* If the primary key has a reference type, this method must call
* EntityOutput.registerPriKeyObject before writing any other fields.
*
* @param output the output data to write to.
*/
void writeSecKeyFields(Object o, EntityOutput output)
throws RefreshException;
/**
* Reads a range of secondary key field values from the given EntityInput,
* reading fields in super classes first and in name order within class.
*
* If the primary key has a reference type, this method must call
* EntityInput.registerPriKeyObject before reading any other fields.
*
* To read all fields, pass -1 for superLevel, zero for startField and
* MAX_FIELD_NUM for endField. Fields from super classes are read
* first.
*
* To read a specific range of fields, pass a non-negative number for
* superLevel and the specific indices of the field range to be read in the
* class at that level.
*
* @param o is the object whose secondary key fields are to be read.
*
* @param input the input data to read from.
*
* @param startField the starting field index in the range of fields to
* read. To read all fields, the startField should be zero.
*
* @param endField the ending field index in the range of fields to read.
* To read all fields, the endField should be MAX_FIELD_NUM.
*
* @param superLevel is a non-negative number to read the fields of the
* class that is the Nth super instance; or a negative number to read
* fields in all classes.
*/
void readSecKeyFields(Object o,
EntityInput input,
int startField,
int endField,
int superLevel)
throws RefreshException;
/**
* Writes all non-key field values to the given EntityOutput, writing
* fields in super classes first and in name order within class.
*
* @param o is the object whose non-key fields are to be written.
*
* @param output the output data to write to.
*/
void writeNonKeyFields(Object o, EntityOutput output)
throws RefreshException;
/**
* Reads a range of non-key field values from the given EntityInput,
* reading fields in super classes first and in name order within class.
*
* To read all fields, pass -1 for superLevel, zero for startField and
* MAX_FIELD_NUM for endField. Fields from super classes are read
* first.
*
* To read a specific range of fields, pass a non-negative number for
* superLevel and the specific indices of the field range to be read in the
* class at that level.
*
* @param o is the object whose non-key fields are to be read.
*
* @param input the input data to read from.
*
* @param startField the starting field index in the range of fields to
* read. To read all fields, the startField should be zero.
*
* @param endField the ending field index in the range of fields to read.
* To read all fields, the endField should be MAX_FIELD_NUM.
*
* @param superLevel is a non-negative number to read the fields of the
* class that is the Nth super instance; or a negative number to read
* fields in all classes.
*/
void readNonKeyFields(Object o,
EntityInput input,
int startField,
int endField,
int superLevel)
throws RefreshException;
/**
* Writes all composite key field values to the given EntityOutput, writing
* in declared field number order.
*
* @param o the composite key object whose fields are to be written.
*
* @param output the output data to write to.
*/
void writeCompositeKeyFields(Object o, EntityOutput output)
throws RefreshException;
/**
* Reads all composite key field values from the given EntityInput,
* reading in declared field number order.
*
* @param o the composite key object whose fields are to be read.
*
* @param input the input data to read from.
*/
void readCompositeKeyFields(Object o, EntityInput input)
throws RefreshException;
/**
* Returns the value of a given field, representing primitives as primitive
* wrapper objects.
*
* @param o is the object containing the key field.
*
* @param field is the field index.
*
* @param superLevel is a positive number to identify the field of the
* class that is the Nth super instance; or zero to identify the field in
* this class.
*
* @param isSecField is true for a secondary key field or false for a
* non-key field.
*
* @return the current field value, or null for a reference type field
* that is null.
*/
Object getField(Object o,
int field,
int superLevel,
boolean isSecField);
/**
* Changes the value of a given field, representing primitives as primitive
* wrapper objects.
*
* @param o is the object containing the key field.
*
* @param field is the field index.
*
* @param superLevel is a positive number to identify the field of the
* class that is the Nth super instance; or zero to identify the field in
* this class.
*
* @param isSecField is true for a secondary key field or false for a
* non-key field.
*
* @param value is the new value of the field, or null to set a reference
* type field to null.
*/
void setField(Object o,
int field,
int superLevel,
boolean isSecField,
Object value);
/**
* Changes the value of the primary key field, representing primitives as
* primitive wrapper objects.
*
* @param o is the object containing the primary key field.
*
* @param field is the field index.
*
* @param superLevel is a positive number to identify the field of the
* class that is the Nth super instance; or zero to identify the field in
* this class.
*
* @param value is the new value of the field, or null to set a reference
* type field to null.
*/
void setPriField(Object o, Object value);
}