001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2000,2008 Oracle. All rights reserved.
005: *
006: * $Id: TupleSerialKeyCreator.java,v 1.30.2.2 2008/01/07 15:14:05 cwl Exp $
007: */
008:
009: package com.sleepycat.bind.serial;
010:
011: import com.sleepycat.bind.tuple.TupleBase;
012: import com.sleepycat.bind.tuple.TupleInput;
013: import com.sleepycat.bind.tuple.TupleOutput;
014: import com.sleepycat.je.DatabaseEntry;
015: import com.sleepycat.je.DatabaseException;
016: import com.sleepycat.je.ForeignKeyNullifier;
017: import com.sleepycat.je.SecondaryDatabase;
018: import com.sleepycat.je.SecondaryKeyCreator;
019:
020: /**
021: * A abstract key creator that uses a tuple key and a serial data entry. This
022: * class takes care of serializing and deserializing the data entry, and
023: * converting the key entry to/from {@link TupleInput} and {@link TupleOutput}
024: * objects.
025: * The following abstract method must be implemented by a concrete subclass
026: * to create the index key using these objects
027: * <ul>
028: * <li> {@link #createSecondaryKey(TupleInput,Object,TupleOutput)} </li>
029: * </ul>
030: * <!-- begin JE only -->
031: * <p>If {@link com.sleepycat.je.ForeignKeyDeleteAction#NULLIFY} was
032: * specified when opening the secondary database, the following method must be
033: * overridden to nullify the foreign index key. If NULLIFY was not specified,
034: * this method need not be overridden.</p>
035: * <ul>
036: * <li> {@link #nullifyForeignKey(Object)} </li>
037: * </ul>
038: * <!-- end JE only -->
039: *
040: * @author Mark Hayes
041: */
042: public abstract class TupleSerialKeyCreator extends TupleBase implements
043: SecondaryKeyCreator, ForeignKeyNullifier {
044:
045: protected SerialBinding dataBinding;
046:
047: /**
048: * Creates a tuple-serial key creator.
049: *
050: * @param classCatalog is the catalog to hold shared class information and
051: * for a database should be a {@link StoredClassCatalog}.
052: *
053: * @param dataClass is the data base class.
054: */
055: public TupleSerialKeyCreator(ClassCatalog classCatalog,
056: Class dataClass) {
057:
058: this (new SerialBinding(classCatalog, dataClass));
059: }
060:
061: /**
062: * Creates a tuple-serial key creator.
063: *
064: * @param dataBinding is the data binding.
065: */
066: public TupleSerialKeyCreator(SerialBinding dataBinding) {
067:
068: this .dataBinding = dataBinding;
069: }
070:
071: // javadoc is inherited
072: public boolean createSecondaryKey(SecondaryDatabase db,
073: DatabaseEntry primaryKeyEntry, DatabaseEntry dataEntry,
074: DatabaseEntry indexKeyEntry) throws DatabaseException {
075:
076: TupleOutput output = getTupleOutput(null);
077: TupleInput primaryKeyInput = entryToInput(primaryKeyEntry);
078: Object dataInput = dataBinding.entryToObject(dataEntry);
079: if (createSecondaryKey(primaryKeyInput, dataInput, output)) {
080: outputToEntry(output, indexKeyEntry);
081: return true;
082: } else {
083: return false;
084: }
085: }
086:
087: // javadoc is inherited
088: public boolean nullifyForeignKey(SecondaryDatabase db,
089: DatabaseEntry dataEntry) throws DatabaseException {
090:
091: Object data = dataBinding.entryToObject(dataEntry);
092: data = nullifyForeignKey(data);
093: if (data != null) {
094: dataBinding.objectToEntry(data, dataEntry);
095: return true;
096: } else {
097: return false;
098: }
099: }
100:
101: /**
102: * Creates the index key entry from primary key tuple entry and
103: * deserialized data entry.
104: *
105: * @param primaryKeyInput is the {@link TupleInput} for the primary key
106: * entry, or null if no primary key entry is used to construct the index
107: * key.
108: *
109: * @param dataInput is the deserialized data entry, or null if no data
110: * entry is used to construct the index key.
111: *
112: * @param indexKeyOutput is the destination index key tuple. For index
113: * keys which are optionally present, no tuple entry should be output to
114: * indicate that the key is not present or null.
115: *
116: * @return true if a key was created, or false to indicate that the key is
117: * not present.
118: */
119: public abstract boolean createSecondaryKey(
120: TupleInput primaryKeyInput, Object dataInput,
121: TupleOutput indexKeyOutput);
122:
123: /**
124: * Clears the index key in the deserialized data entry.
125: *
126: * <p>On entry the data parameter contains the index key to be cleared. It
127: * should be changed by this method such that {@link #createSecondaryKey}
128: * will return false. Other fields in the data object should remain
129: * unchanged.</p>
130: *
131: * @param data is the source and destination deserialized data
132: * entry.
133: *
134: * @return the destination data object, or null to indicate that the
135: * key is not present and no change is necessary. The data returned may
136: * be the same object passed as the data parameter or a newly created
137: * object.
138: */
139: public Object nullifyForeignKey(Object data) {
140:
141: return null;
142: }
143: }
|