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