• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/db-4.7.25.NC/java/src/com/sleepycat/persist/impl/
1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2002,2008 Oracle.  All rights reserved.
5 *
6 * $Id: RecordOutput.java,v 1.1 2008/02/07 17:12:27 mark Exp $
7 */
8
9package com.sleepycat.persist.impl;
10
11import com.sleepycat.bind.tuple.TupleOutput;
12import com.sleepycat.persist.raw.RawObject;
13
14/**
15 * Implements EntityOutput to write record key-data pairs.  Extends TupleOutput
16 * to implement the subset of TupleOutput methods that are defined in the
17 * EntityOutput interface.
18 *
19 * @author Mark Hayes
20 */
21class RecordOutput extends TupleOutput implements EntityOutput {
22
23    private Catalog catalog;
24    private boolean rawAccess;
25    private VisitedObjects visited;
26
27    /**
28     * Creates a new output with an empty/null VisitedObjects set.
29     */
30    RecordOutput(Catalog catalog, boolean rawAccess) {
31
32        super();
33        this.catalog = catalog;
34        this.rawAccess = rawAccess;
35    }
36
37    /**
38     * @see EntityInput#writeObject
39     */
40    public void writeObject(Object o, Format fieldFormat) {
41
42        /* For a null instance, write a zero format ID. */
43        if (o == null) {
44            writePackedInt(Format.ID_NULL);
45            return;
46        }
47
48        /*
49         * For an already visited instance, output a reference to it.  The
50         * reference is the negation of the visited offset minus one.
51         */
52        if (visited != null) {
53            int offset = visited.getOffset(o);
54            if (offset == VisitedObjects.PROHIBIT_REF_OFFSET) {
55                throw new IllegalArgumentException
56                    (VisitedObjects.PROHIBIT_NESTED_REF_MSG);
57            }
58            if (offset > 0) {
59                writePackedInt(-(offset + 1));
60                return;
61            }
62        }
63
64        /*
65         * Get and validate the format.  Catalog.getFormat(Class) throws
66         * IllegalArgumentException if the class is not persistent.  We don't
67         * need to check the fieldFormat (and it will be null) for non-raw
68         * access because field type checking is enforced by Java.
69         */
70        Format format;
71        if (rawAccess) {
72            format = RawAbstractInput.checkRawType(catalog, o, fieldFormat);
73        } else {
74            format = catalog.getFormat(o.getClass());
75        }
76        if (format.getProxiedFormat() != null) {
77            throw new IllegalArgumentException
78                ("May not store proxy classes directly: " +
79                 format.getClassName());
80        }
81        if (format.isEntity()) {
82            throw new IllegalArgumentException
83                ("References to entities are not allowed: " +
84                 o.getClass().getName());
85        }
86
87        /*
88         * Remember that we visited this instance.  Certain formats
89         * (ProxiedFormat for example) prohibit nested fields that reference
90         * the parent object. [#15815]
91         */
92        if (visited == null) {
93            visited = new VisitedObjects();
94        }
95        boolean prohibitNestedRefs = format.areNestedRefsProhibited();
96        int visitedOffset = size();
97        int visitedIndex = visited.add(o, prohibitNestedRefs ?
98            VisitedObjects.PROHIBIT_REF_OFFSET :
99            visitedOffset);
100
101        /* Finally, write the formatId and object value. */
102        writePackedInt(format.getId());
103        format.writeObject(o, this, rawAccess);
104
105        /* Always allow references from siblings that follow. */
106        if (prohibitNestedRefs) {
107            visited.setOffset(visitedIndex, visitedOffset);
108        }
109    }
110
111    /**
112     * @see EntityInput#writeKeyObject
113     */
114    public void writeKeyObject(Object o, Format fieldFormat) {
115
116        /* Key objects must not be null and must be of the declared class. */
117        if (o == null) {
118            throw new IllegalArgumentException
119                ("Key field object may not be null");
120        }
121        Format format;
122        if (rawAccess) {
123            if (o instanceof RawObject) {
124                format = (Format) ((RawObject) o).getType();
125            } else {
126                format = catalog.getFormat(o.getClass());
127                /* Expect primitive wrapper class in raw mode. */
128                if (fieldFormat.isPrimitive()) {
129                    fieldFormat = fieldFormat.getWrapperFormat();
130                }
131            }
132        } else {
133            format = catalog.getFormat(o.getClass());
134        }
135        if (fieldFormat != format) {
136            throw new IllegalArgumentException
137                ("The key field object class (" + o.getClass().getName() +
138                 ") must be the field's declared class: " +
139                 fieldFormat.getClassName());
140        }
141
142        /* Write the object value (no formatId is written for keys). */
143        fieldFormat.writeObject(o, this, rawAccess);
144    }
145
146    /**
147     * @see EntityInput#registerPriKeyObject
148     */
149    public void registerPriKeyObject(Object o) {
150
151        /*
152         * PRI_KEY_VISITED_OFFSET is used as the visited offset to indicate
153         * that the visited object is stored in the primary key byte array.
154         */
155        if (visited == null) {
156            visited = new VisitedObjects();
157        }
158        visited.add(o, VisitedObjects.PRI_KEY_VISITED_OFFSET);
159    }
160
161    /**
162     * @see EntityInput#writeArrayLength
163     */
164    public void writeArrayLength(int length) {
165        writePackedInt(length);
166    }
167
168    /**
169     * @see EntityInput#writeEnumConstant
170     */
171    public void writeEnumConstant(String[] names, int index) {
172        writePackedInt(index);
173    }
174}
175