1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002,2008 Oracle. All rights reserved. 5 * 6 * $Id: Accessor.java,v 1.1 2008/02/07 17:12:27 mark Exp $ 7 */ 8 9package com.sleepycat.persist.impl; 10 11/** 12 * Field binding operations implemented via reflection (ReflectionAccessor) or 13 * bytecode enhancement (EnhancedAccessor). 14 * 15 * <p>Normally we read the set of all secondary key fields first and then the 16 * set of all non-key fields, reading each set in order of field name. But 17 * when reading an old format record we must account for the following 18 * class evolution conversions:</p> 19 * <ul> 20 * <li>Convert a field: pass value thru converter</li> 21 * <li>Widen a field type: pass value thru widener</li> 22 * <li>Add a field: don't read the new field</li> 23 * <li>Delete a field: skip the deleted field</li> 24 * <li>Rename a field: read field in a different order</li> 25 * </ul> 26 * <p>To support these operations, the methods for reading fields allow reading 27 * specific ranges of fields as well as all fields. For example, all fields 28 * up to a deleted field could be read, and then all fields from the following 29 * field onward.</p> 30 * 31 * @author Mark Hayes 32 */ 33interface Accessor { 34 35 /** 36 * A large field value to use instead of Integer.MAX_VALUE, to work around 37 * Java JIT compiler bug when doing an (X <= Integer.MAX_VALUE) as would be 38 * done in readXxxKeyFields methods. 39 */ 40 final int MAX_FIELD_NUM = Integer.MAX_VALUE - 1; 41 42 /** 43 * Creates a new instance of the target class using its default 44 * constructor. 45 */ 46 Object newInstance(); 47 48 /** 49 * Creates a new one dimensional array of the given length, having the 50 * target class as its component type. 51 * 52 * <p>Using a special method for a one dimensional array, which can be 53 * implemented by bytecode generation, is a compromise. We use reflection 54 * to create multidimensional arrays. We could in the future generate code 55 * to create arrays as they are encountered, if there is a need to avoid 56 * reflection for multidimensional arrays.</p> 57 */ 58 Object newArray(int len); 59 60 /** 61 * Returns whether the primary key field is null (for a reference type) or 62 * zero (for a primitive integer type). Null and zero are used as an 63 * indication that the key should be assigned from a sequence. 64 */ 65 boolean isPriKeyFieldNullOrZero(Object o); 66 67 /** 68 * Writes the primary key field value to the given EntityOutput. 69 * 70 * <p>To write a primary key with a reference type, this method must call 71 * EntityOutput.writeKeyObject.</p> 72 * 73 * @param o is the object whose primary key field is to be written. 74 * 75 * @param output the output data to write to. 76 */ 77 void writePriKeyField(Object o, EntityOutput output); 78 79 /** 80 * Reads the primary key field value from the given EntityInput. 81 * 82 * <p>To read a primary key with a reference type, this method must call 83 * EntityInput.readKeyObject.</p> 84 * 85 * @param o is the object whose primary key field is to be read. 86 * 87 * @param input the input data to read from. 88 */ 89 void readPriKeyField(Object o, EntityInput input); 90 91 /** 92 * Writes all secondary key field values to the given EntityOutput, 93 * writing fields in super classes first and in name order within class. 94 * 95 * @param o is the object whose secondary key fields are to be written. 96 * 97 * <p>If the primary key has a reference type, this method must call 98 * EntityOutput.registerPriKeyObject before writing any other fields.</p> 99 * 100 * @param output the output data to write to. 101 */ 102 void writeSecKeyFields(Object o, EntityOutput output); 103 104 /** 105 * Reads a range of secondary key field values from the given EntityInput, 106 * reading fields in super classes first and in name order within class. 107 * 108 * <p>If the primary key has a reference type, this method must call 109 * EntityInput.registerPriKeyObject before reading any other fields.</p> 110 * 111 * <p>To read all fields, pass -1 for superLevel, zero for startField and 112 * MAX_FIELD_NUM for endField. Fields from super classes are read 113 * first.</p> 114 * 115 * <p>To read a specific range of fields, pass a non-negative number for 116 * superLevel and the specific indices of the field range to be read in the 117 * class at that level.</p> 118 * 119 * @param o is the object whose secondary key fields are to be read. 120 * 121 * @param input the input data to read from. 122 * 123 * @param startField the starting field index in the range of fields to 124 * read. To read all fields, the startField should be zero. 125 * 126 * @param endField the ending field index in the range of fields to read. 127 * To read all fields, the endField should be MAX_FIELD_NUM. 128 * 129 * @param superLevel is a non-negative number to read the fields of the 130 * class that is the Nth super instance; or a negative number to read 131 * fields in all classes. 132 */ 133 void readSecKeyFields(Object o, 134 EntityInput input, 135 int startField, 136 int endField, 137 int superLevel); 138 139 /** 140 * Writes all non-key field values to the given EntityOutput, writing 141 * fields in super classes first and in name order within class. 142 * 143 * @param o is the object whose non-key fields are to be written. 144 * 145 * @param output the output data to write to. 146 */ 147 void writeNonKeyFields(Object o, EntityOutput output); 148 149 /** 150 * Reads a range of non-key field values from the given EntityInput, 151 * reading fields in super classes first and in name order within class. 152 * 153 * <p>To read all fields, pass -1 for superLevel, zero for startField and 154 * MAX_FIELD_NUM for endField. Fields from super classes are read 155 * first.</p> 156 * 157 * <p>To read a specific range of fields, pass a non-negative number for 158 * superLevel and the specific indices of the field range to be read in the 159 * class at that level.</p> 160 * 161 * @param o is the object whose non-key fields are to be read. 162 * 163 * @param input the input data to read from. 164 * 165 * @param startField the starting field index in the range of fields to 166 * read. To read all fields, the startField should be zero. 167 * 168 * @param endField the ending field index in the range of fields to read. 169 * To read all fields, the endField should be MAX_FIELD_NUM. 170 * 171 * @param superLevel is a non-negative number to read the fields of the 172 * class that is the Nth super instance; or a negative number to read 173 * fields in all classes. 174 */ 175 void readNonKeyFields(Object o, 176 EntityInput input, 177 int startField, 178 int endField, 179 int superLevel); 180 181 /** 182 * Returns the value of a given field, representing primitives as primitive 183 * wrapper objects. 184 * 185 * @param o is the object containing the key field. 186 * 187 * @param field is the field index. 188 * 189 * @param superLevel is a positive number to identify the field of the 190 * class that is the Nth super instance; or zero to identify the field in 191 * this class. 192 * 193 * @param isSecField is true for a secondary key field or false for a 194 * non-key field. 195 * 196 * @return the current field value, or null for a reference type field 197 * that is null. 198 */ 199 Object getField(Object o, 200 int field, 201 int superLevel, 202 boolean isSecField); 203 204 /** 205 * Changes the value of a given field, representing primitives as primitive 206 * wrapper objects. 207 * 208 * @param o is the object containing the key field. 209 * 210 * @param field is the field index. 211 * 212 * @param superLevel is a positive number to identify the field of the 213 * class that is the Nth super instance; or zero to identify the field in 214 * this class. 215 * 216 * @param isSecField is true for a secondary key field or false for a 217 * non-key field. 218 * 219 * @param value is the new value of the field, or null to set a reference 220 * type field to null. 221 */ 222 void setField(Object o, 223 int field, 224 int superLevel, 225 boolean isSecField, 226 Object value); 227} 228