1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2000-2009 Oracle. All rights reserved. 5 * 6 * $Id$ 7 */ 8 9package com.sleepycat.bind.serial; 10 11import com.sleepycat.bind.tuple.TupleBase; 12import com.sleepycat.bind.tuple.TupleInput; 13import com.sleepycat.bind.tuple.TupleOutput; 14import com.sleepycat.db.DatabaseEntry; 15import com.sleepycat.db.ForeignKeyNullifier; 16import com.sleepycat.db.SecondaryDatabase; 17import com.sleepycat.db.SecondaryKeyCreator; 18 19/** 20 * A abstract key creator that uses a tuple key and a serial data entry. This 21 * class takes care of serializing and deserializing the data entry, and 22 * converting the key entry to/from {@link TupleInput} and {@link TupleOutput} 23 * objects. 24 * The following abstract method must be implemented by a concrete subclass 25 * to create the index key using these objects 26 * <ul> 27 * <li> {@link #createSecondaryKey(TupleInput,Object,TupleOutput)} </li> 28 * </ul> 29 * <p>If {@link com.sleepycat.db.ForeignKeyDeleteAction#NULLIFY} was 30 * specified when opening the secondary database, the following method must be 31 * overridden to nullify the foreign index key. If NULLIFY was not specified, 32 * this method need not be overridden.</p> 33 * <ul> 34 * <li> {@link #nullifyForeignKey(Object)} </li> 35 * </ul> 36 * 37 * @see <a href="SerialBinding.html#evolution">Class Evolution</a> 38 * 39 * @author Mark Hayes 40 */ 41public abstract class TupleSerialKeyCreator<D> extends TupleBase 42 implements SecondaryKeyCreator, ForeignKeyNullifier { 43 44 protected SerialBinding<D> dataBinding; 45 46 /** 47 * Creates a tuple-serial key creator. 48 * 49 * @param classCatalog is the catalog to hold shared class information and 50 * for a database should be a {@link StoredClassCatalog}. 51 * 52 * @param dataClass is the data base class. 53 */ 54 public TupleSerialKeyCreator(ClassCatalog classCatalog, 55 Class<D> dataClass) { 56 57 this(new SerialBinding<D>(classCatalog, dataClass)); 58 } 59 60 /** 61 * Creates a tuple-serial key creator. 62 * 63 * @param dataBinding is the data binding. 64 */ 65 public TupleSerialKeyCreator(SerialBinding<D> dataBinding) { 66 67 this.dataBinding = dataBinding; 68 } 69 70 // javadoc is inherited 71 public boolean createSecondaryKey(SecondaryDatabase db, 72 DatabaseEntry primaryKeyEntry, 73 DatabaseEntry dataEntry, 74 DatabaseEntry indexKeyEntry) { 75 TupleOutput output = getTupleOutput(null); 76 TupleInput primaryKeyInput = entryToInput(primaryKeyEntry); 77 D dataInput = dataBinding.entryToObject(dataEntry); 78 if (createSecondaryKey(primaryKeyInput, dataInput, output)) { 79 outputToEntry(output, indexKeyEntry); 80 return true; 81 } else { 82 return false; 83 } 84 } 85 86 // javadoc is inherited 87 public boolean nullifyForeignKey(SecondaryDatabase db, 88 DatabaseEntry dataEntry) { 89 D data = dataBinding.entryToObject(dataEntry); 90 data = nullifyForeignKey(data); 91 if (data != null) { 92 dataBinding.objectToEntry(data, dataEntry); 93 return true; 94 } else { 95 return false; 96 } 97 } 98 99 /** 100 * Creates the index key entry from primary key tuple entry and 101 * deserialized data entry. 102 * 103 * @param primaryKeyInput is the {@link TupleInput} for the primary key 104 * entry, or null if no primary key entry is used to construct the index 105 * key. 106 * 107 * @param dataInput is the deserialized data entry, or null if no data 108 * entry is used to construct the index key. 109 * 110 * @param indexKeyOutput is the destination index key tuple. For index 111 * keys which are optionally present, no tuple entry should be output to 112 * indicate that the key is not present or null. 113 * 114 * @return true if a key was created, or false to indicate that the key is 115 * not present. 116 */ 117 public abstract boolean createSecondaryKey(TupleInput primaryKeyInput, 118 D dataInput, 119 TupleOutput indexKeyOutput); 120 121 /** 122 * Clears the index key in the deserialized data entry. 123 * 124 * <p>On entry the data parameter contains the index key to be cleared. It 125 * should be changed by this method such that {@link #createSecondaryKey} 126 * will return false. Other fields in the data object should remain 127 * unchanged.</p> 128 * 129 * @param data is the source and destination deserialized data 130 * entry. 131 * 132 * @return the destination data object, or null to indicate that the 133 * key is not present and no change is necessary. The data returned may 134 * be the same object passed as the data parameter or a newly created 135 * object. 136 */ 137 public D nullifyForeignKey(D data) { 138 139 return null; 140 } 141} 142