001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2002,2008 Oracle. All rights reserved.
005: *
006: * $Id: Accessor.java,v 1.10.2.3 2008/01/07 15:14:19 cwl Exp $
007: */
008:
009: package com.sleepycat.persist.impl;
010:
011: /**
012: * Field binding operations implemented via reflection (ReflectionAccessor) or
013: * bytecode enhancement (EnhancedAccessor).
014: *
015: * <p>Normally we read the set of all secondary key fields first and then the
016: * set of all non-key fields, reading each set in order of field name. But
017: * when reading an old format record we must account for the following
018: * class evolution conversions:</p>
019: * <ul>
020: * <li>Convert a field: pass value thru converter</li>
021: * <li>Widen a field type: pass value thru widener</li>
022: * <li>Add a field: don't read the new field</li>
023: * <li>Delete a field: skip the deleted field</li>
024: * <li>Rename a field: read field in a different order</li>
025: * </ul>
026: * <p>To support these operations, the methods for reading fields allow reading
027: * specific ranges of fields as well as all fields. For example, all fields
028: * up to a deleted field could be read, and then all fields from the following
029: * field onward.</p>
030: *
031: * @author Mark Hayes
032: */
033: interface Accessor {
034:
035: /**
036: * A large field value to use instead of Integer.MAX_VALUE, to work around
037: * Java JIT compiler bug when doing an (X <= Integer.MAX_VALUE) as would be
038: * done in readXxxKeyFields methods.
039: */
040: final int MAX_FIELD_NUM = Integer.MAX_VALUE - 1;
041:
042: /**
043: * Creates a new instance of the target class using its default
044: * constructor.
045: */
046: Object newInstance();
047:
048: /**
049: * Creates a new one dimensional array of the given length, having the
050: * target class as its component type.
051: *
052: * <p>Using a special method for a one dimensional array, which can be
053: * implemented by bytecode generation, is a compromise. We use reflection
054: * to create multidimensional arrays. We could in the future generate code
055: * to create arrays as they are encountered, if there is a need to avoid
056: * reflection for multidimensional arrays.</p>
057: */
058: Object newArray(int len);
059:
060: /**
061: * Returns whether the primary key field is null (for a reference type) or
062: * zero (for a primitive integer type). Null and zero are used as an
063: * indication that the key should be assigned from a sequence.
064: */
065: boolean isPriKeyFieldNullOrZero(Object o);
066:
067: /**
068: * Writes the primary key field value to the given EntityOutput.
069: *
070: * <p>To write a primary key with a reference type, this method must call
071: * EntityOutput.writeKeyObject.</p>
072: *
073: * @param o is the object whose primary key field is to be written.
074: *
075: * @param output the output data to write to.
076: */
077: void writePriKeyField(Object o, EntityOutput output);
078:
079: /**
080: * Reads the primary key field value from the given EntityInput.
081: *
082: * <p>To read a primary key with a reference type, this method must call
083: * EntityInput.readKeyObject.</p>
084: *
085: * @param o is the object whose primary key field is to be read.
086: *
087: * @param input the input data to read from.
088: */
089: void readPriKeyField(Object o, EntityInput input);
090:
091: /**
092: * Writes all secondary key field values to the given EntityOutput,
093: * writing fields in super classes first and in name order within class.
094: *
095: * @param o is the object whose secondary key fields are to be written.
096: *
097: * <p>If the primary key has a reference type, this method must call
098: * EntityOutput.registerPriKeyObject before writing any other fields.</p>
099: *
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, EntityInput input, int startField,
134: int endField, int super Level);
135:
136: /**
137: * Writes all non-key field values to the given EntityOutput, writing
138: * fields in super classes first and in name order within class.
139: *
140: * @param o is the object whose non-key fields are to be written.
141: *
142: * @param output the output data to write to.
143: */
144: void writeNonKeyFields(Object o, EntityOutput output);
145:
146: /**
147: * Reads a range of non-key field values from the given EntityInput,
148: * reading fields in super classes first and in name order within class.
149: *
150: * <p>To read all fields, pass -1 for superLevel, zero for startField and
151: * MAX_FIELD_NUM for endField. Fields from super classes are read
152: * first.</p>
153: *
154: * <p>To read a specific range of fields, pass a non-negative number for
155: * superLevel and the specific indices of the field range to be read in the
156: * class at that level.</p>
157: *
158: * @param o is the object whose non-key fields are to be read.
159: *
160: * @param input the input data to read from.
161: *
162: * @param startField the starting field index in the range of fields to
163: * read. To read all fields, the startField should be zero.
164: *
165: * @param endField the ending field index in the range of fields to read.
166: * To read all fields, the endField should be MAX_FIELD_NUM.
167: *
168: * @param superLevel is a non-negative number to read the fields of the
169: * class that is the Nth super instance; or a negative number to read
170: * fields in all classes.
171: */
172: void readNonKeyFields(Object o, EntityInput input, int startField,
173: int endField, int super Level);
174:
175: /**
176: * Returns the value of a given field, representing primitives as primitive
177: * wrapper objects.
178: *
179: * @param o is the object containing the key field.
180: *
181: * @param field is the field index.
182: *
183: * @param superLevel is a positive number to identify the field of the
184: * class that is the Nth super instance; or zero to identify the field in
185: * this class.
186: *
187: * @param isSecField is true for a secondary key field or false for a
188: * non-key field.
189: *
190: * @return the current field value, or null for a reference type field
191: * that is null.
192: */
193: Object getField(Object o, int field, int super Level,
194: boolean isSecField);
195:
196: /**
197: * Changes the value of a given field, representing primitives as primitive
198: * wrapper objects.
199: *
200: * @param o is the object containing the key field.
201: *
202: * @param field is the field index.
203: *
204: * @param superLevel is a positive number to identify the field of the
205: * class that is the Nth super instance; or zero to identify the field in
206: * this class.
207: *
208: * @param isSecField is true for a secondary key field or false for a
209: * non-key field.
210: *
211: * @param value is the new value of the field, or null to set a reference
212: * type field to null.
213: */
214: void setField(Object o, int field, int super Level,
215: boolean isSecField, Object value);
216: }
|