KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > persist > impl > RecordInput


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: RecordInput.java,v 1.4 2006/10/30 21:14:32 bostic Exp $
7  */

8
9 package com.sleepycat.persist.impl;
10
11 import com.sleepycat.bind.tuple.TupleInput;
12 import com.sleepycat.je.DatabaseEntry;
13
14 /**
15  * Implements EntityInput to read record key-data pairs. Extends TupleInput to
16  * implement the subset of TupleInput methods that are defined in the
17  * EntityInput interface.
18  *
19  * @author Mark Hayes
20  */

21 class RecordInput extends TupleInput implements EntityInput {
22
23     private Catalog catalog;
24     private boolean rawAccess;
25     private VisitedObjects visited;
26     private DatabaseEntry priKeyEntry;
27     private int priKeyFormatId;
28
29     /**
30      * Creates a new input with a empty/null VisitedObjects set.
31      */

32     RecordInput(Catalog catalog,
33                 boolean rawAccess,
34                 DatabaseEntry priKeyEntry,
35                 int priKeyFormatId,
36                 byte[] buffer,
37                 int offset,
38                 int length) {
39         super(buffer, offset, length);
40         this.catalog = catalog;
41         this.rawAccess = rawAccess;
42         this.priKeyEntry = priKeyEntry;
43         this.priKeyFormatId = priKeyFormatId;
44     }
45
46     /**
47      * Copy contructor where a new offset can be specified.
48      */

49     private RecordInput(RecordInput other, int offset) {
50         this(other.catalog, other.rawAccess, other.priKeyEntry,
51              other.priKeyFormatId, other.buf, offset, other.len);
52         visited = other.visited;
53     }
54
55     /**
56      * Copy contructor where a DatabaseEntry can be specified.
57      */

58     private RecordInput(RecordInput other, DatabaseEntry entry) {
59         this(other.catalog, other.rawAccess, other.priKeyEntry,
60              other.priKeyFormatId, entry.getData(), entry.getOffset(),
61              entry.getSize());
62         visited = other.visited;
63     }
64
65     /**
66      * @see EntityInput#getCatalog
67      */

68     public Catalog getCatalog() {
69         return catalog;
70     }
71     
72     /**
73      * @see EntityInput#isRawAccess
74      */

75     public boolean isRawAccess() {
76         return rawAccess;
77     }
78
79     /**
80      * @see EntityInput#setRawAccess
81      */

82     public boolean setRawAccess(boolean rawAccessParam) {
83         boolean original = rawAccess;
84         rawAccess = rawAccessParam;
85         return original;
86     }
87
88     /**
89      * @see EntityInput#readObject
90      */

91     public Object JavaDoc readObject() {
92
93         /* Save the current offset before reading the format ID. */
94         int visitedOffset = off;
95         RecordInput useInput = this;
96         int formatId = readPackedInt();
97         Object JavaDoc o = null;
98
99         /* For a zero format ID, return a null instance. */
100         if (formatId == Format.ID_NULL) {
101             return null;
102         }
103
104         /* For a negative format ID, lookup an already visited instance. */
105         if (formatId < 0) {
106             int offset = (-(formatId + 1));
107             if (visited != null) {
108                 o = visited.getObject(offset);
109             }
110             if (o != null) {
111                 /* Return a previously visited object. */
112                 return o;
113             } else {
114
115                 /*
116                  * When reading starts from a non-zero offset, we may have to
117                  * go back in the stream and read the referenced object. This
118                  * happens when reading secondary key fields.
119                  */

120                 visitedOffset = offset;
121                 if (offset == EntityOutput.PRI_KEY_VISITED_OFFSET) {
122                     assert priKeyEntry != null && priKeyFormatId > 0;
123                     useInput = new RecordInput(this, priKeyEntry);
124                     formatId = priKeyFormatId;
125                 } else {
126                     useInput = new RecordInput(this, offset);
127                     formatId = useInput.readPackedInt();
128                 }
129             }
130         }
131
132         /* Create the object using the format indicated. */
133         Format format = catalog.getFormat(formatId);
134         Reader reader = format.getReader();
135         o = reader.newInstance(useInput, rawAccess);
136
137         /*
138          * Add newly created object to the set of visited objects. This must
139          * be done before calling Reader.readObject, in case the object
140          * contains a reference to itself.
141          */

142         if (visited == null) {
143             visited = new VisitedObjects();
144         }
145         visited.add(o, visitedOffset);
146
147         /*
148          * Finish reading the object. Then replace it in the visited list in
149          * case a converted object is returned by readObject.
150          */

151         Object JavaDoc o2 = reader.readObject(o, useInput, rawAccess);
152         if (o != o2) {
153             visited.replaceObject(o, o2);
154         }
155         return o2;
156     }
157
158     /**
159      * @see EntityInput#readKeyObject
160      */

161     public Object JavaDoc readKeyObject(Format format) {
162
163         /* Create and read the object using the given key format. */
164         Reader reader = format.getReader();
165         Object JavaDoc o = reader.newInstance(this, rawAccess);
166         return reader.readObject(o, this, rawAccess);
167     }
168
169     /**
170      * Called when copying secondary keys, for an input that is positioned on
171      * the secondary key field. Handles references to previously occurring
172      * objects, returning a different RecordInput than this one if appropriate.
173      */

174     KeyLocation getKeyLocation(Format fieldFormat) {
175         RecordInput input = this;
176         if (!fieldFormat.isPrimitive()) {
177             int formatId = input.readPackedInt();
178             if (formatId == Format.ID_NULL) {
179                 /* Key field is null. */
180                 return null;
181             }
182             if (formatId < 0) {
183                 int offset = (-(formatId + 1));
184                 if (offset == EntityOutput.PRI_KEY_VISITED_OFFSET) {
185                     assert priKeyEntry != null && priKeyFormatId > 0;
186                     input = new RecordInput(this, priKeyEntry);
187                     formatId = priKeyFormatId;
188                 } else {
189                     input = new RecordInput(this, offset);
190                     formatId = input.readPackedInt();
191                 }
192             }
193             fieldFormat = catalog.getFormat(formatId);
194         }
195         /* Key field is non-null. */
196         return new KeyLocation(input, fieldFormat);
197     }
198
199     /**
200      * @see EntityInput#registerPriKeyObject
201      */

202     public void registerPriKeyObject(Object JavaDoc o) {
203
204         /*
205          * PRI_KEY_VISITED_OFFSET is used as the visited offset to indicate
206          * that the visited object is stored in the primary key byte array.
207          */

208         if (visited == null) {
209             visited = new VisitedObjects();
210         }
211         visited.add(o, EntityOutput.PRI_KEY_VISITED_OFFSET);
212     }
213
214     /**
215      * @see EntityInput#skipField
216      */

217     public void skipField(Format declaredFormat) {
218         if (declaredFormat != null && declaredFormat.isPrimitive()) {
219             declaredFormat.skipContents(this);
220         } else {
221             int formatId = readPackedInt();
222             if (formatId > 0) {
223                 Format format = catalog.getFormat(formatId);
224                 format.skipContents(this);
225             }
226         }
227     }
228
229     public int readArrayLength() {
230         return readPackedInt();
231     }
232
233     public int readEnumConstant(String JavaDoc[] names) {
234         return readPackedInt();
235     }
236 }
237
Popular Tags