• 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: PersistEntityBinding.java,v 1.1 2008/02/07 17:12:27 mark Exp $
7 */
8
9package com.sleepycat.persist.impl;
10
11import com.sleepycat.bind.EntityBinding;
12import com.sleepycat.bind.tuple.TupleBase;
13import com.sleepycat.db.DatabaseEntry;
14import com.sleepycat.persist.model.EntityModel;
15import com.sleepycat.persist.raw.RawObject;
16
17/**
18 * A persistence entity binding for a given entity class.
19 *
20 * @author Mark Hayes
21 */
22public class PersistEntityBinding implements EntityBinding {
23
24    PersistCatalog catalog;
25    Format entityFormat;
26    boolean rawAccess;
27    PersistKeyAssigner keyAssigner;
28
29    /**
30     * Creates a key binding for a given entity class.
31     */
32    public PersistEntityBinding(PersistCatalog catalog,
33                                String entityClassName,
34                                boolean rawAccess) {
35        this.catalog = catalog;
36        if (rawAccess) {
37            entityFormat = catalog.getFormat(entityClassName);
38            if (entityFormat == null || !entityFormat.isEntity()) {
39                throw new IllegalArgumentException
40                    ("Not an entity class: " + entityClassName);
41            }
42        } else {
43            Class entityCls;
44            try {
45                entityCls = EntityModel.classForName(entityClassName);
46            } catch (ClassNotFoundException e) {
47                throw new IllegalArgumentException(e);
48            }
49            entityFormat = catalog.getFormat(entityCls);
50        }
51        this.rawAccess = rawAccess;
52    }
53
54    public PersistKeyAssigner getKeyAssigner() {
55        return keyAssigner;
56    }
57
58    public Object entryToObject(DatabaseEntry key, DatabaseEntry data) {
59        return readEntity(catalog, key, data, rawAccess);
60    }
61
62    /**
63     * Creates the instance, reads the entity key first to track visited
64     * entities correctly, then reads the data and returns the entity.
65     *
66     * This is a special case of EntityInput.readObject for a top level entity.
67     * Special treatments are:
68     * - The formatId must be >= 0; since this is the top level instance, it
69     *   cannot refer to a visited object nor be a null reference.
70     * - The resulting entity is not added to the visited object set; entities
71     *   cannot be referenced by another (or the same) entity.
72     * - Reader.readPriKey must be called prior to calling Reader.readObject.
73     */
74    static Object readEntity(Catalog catalog,
75                             DatabaseEntry key,
76                             DatabaseEntry data,
77                             boolean rawAccess) {
78        RecordInput keyInput = new RecordInput
79            (catalog, rawAccess, null, 0,
80             key.getData(), key.getOffset(), key.getSize());
81        RecordInput dataInput = new RecordInput
82            (catalog, rawAccess, null, 0,
83             data.getData(), data.getOffset(), data.getSize());
84        int formatId = dataInput.readPackedInt();
85        Format format = catalog.getFormat(formatId);
86        Reader reader = format.getReader();
87        Object entity = reader.newInstance(dataInput, rawAccess);
88        reader.readPriKey(entity, keyInput, rawAccess);
89        return reader.readObject(entity, dataInput, rawAccess);
90    }
91
92    public void objectToData(Object entity, DatabaseEntry data) {
93        Format format = getValidFormat(entity);
94        writeEntity(format, catalog, entity, data, rawAccess);
95    }
96
97    /**
98     * Writes the formatId and object, and returns the bytes.
99     *
100     * This is a special case of EntityOutput.writeObject for a top level
101     * entity.  Special treatments are:
102     * - The entity may not be null.
103     * - The entity is not added to the visited object set nor checked for
104     *   existence in the visited object set; entities cannot be referenced by
105     *   another (or the same) entity.
106     */
107    static void writeEntity(Format format,
108                            Catalog catalog,
109                            Object entity,
110                            DatabaseEntry data,
111                            boolean rawAccess) {
112        RecordOutput output = new RecordOutput(catalog, rawAccess);
113        output.writePackedInt(format.getId());
114        format.writeObject(entity, output, rawAccess);
115        TupleBase.outputToEntry(output, data);
116    }
117
118    public void objectToKey(Object entity, DatabaseEntry key) {
119
120        /*
121         * Write the primary key field as a special case since the output
122         * format is for a key binding, not entity data.
123         */
124        Format format = getValidFormat(entity);
125        RecordOutput output = new RecordOutput(catalog, rawAccess);
126
127        /* Write the primary key and return the bytes. */
128        format.writePriKey(entity, output, rawAccess);
129        TupleBase.outputToEntry(output, key);
130    }
131
132    /**
133     * Returns the format for the given entity and validates it, throwing an
134     * exception if it is invalid for this binding.
135     */
136    private Format getValidFormat(Object entity) {
137
138        /* A null entity is not allowed. */
139        if (entity == null) {
140            throw new IllegalArgumentException("An entity may not be null");
141        }
142
143        /*
144         * Get the format.  getFormat throws IllegalArgumentException if the
145         * class is not persistent.
146         */
147        Format format;
148        if (rawAccess) {
149            if (!(entity instanceof RawObject)) {
150                throw new IllegalArgumentException
151                    ("Entity must be a RawObject");
152            }
153            format = (Format) ((RawObject) entity).getType();
154        } else {
155            format = catalog.getFormat(entity.getClass());
156        }
157
158        /* Check that the entity class/subclass is valid for this binding. */
159        if (format.getEntityFormat() != entityFormat) {
160            throw new IllegalArgumentException
161                ("The entity class (" + format.getClassName() +
162                 ") must be this entity class or a subclass of it: " +
163                 entityFormat.getClassName());
164        }
165
166        return format;
167    }
168}
169